从C#COM方法返回对象和内存所有权
Returning object from C# COM method and memory ownership
我在C#中实现了一个COM组件:
[ComVisible(true)]
[System.Runtime.InteropServices.Guid("E052BB1C-7ADC-47F4-99E1-9407E2FA0AA2")]
public interface IColorRamps
{
IColorRamp getColorRamp();
}
[ComVisible(true)]
[Guid("EE47F2F2-0AD9-437C-8815-D570EACF2C07")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("ColorRamps.ColorRamps")]
public class ColorRamps : IColorRamps
{
public IColorRamp getColorRamp() { ... }
}
我从C++调用这个:
IColorRampPtr colorRamp;
{
ColorRamps::IColorRampsPtr colorRamps(ColorRamps::CLSID_ColorRamps);
HRESULT hr = colorRamps->getColorRamp(&colorRamp);
colorRamp.AddRef(); // Should I do this??
}
起初,我没有AddRef((调用,除了在多次运行此代码后,在"R6025(纯虚拟函数调用(运行时错误"上出现奇怪的崩溃外,一切似乎都正常。
自动生成的.tlh文件中的签名是:
virtual HRESULT __stdcall getColorRamp(/*[out,retval]*/ struct IColorRamp * * pRetVal ) = 0;
在C++中调用这样的函数时,我习惯于函数本身执行AddRef((并将内存所有权传递给调用者。C#中不是这样吗?
我没有在ColorRamps.getColorRamp((.内部调用Marshal.AddRef((
发生这种情况的最可能原因是Release()
是指针,而不是.NET在返回之前忘记了AddRef()
(提示:.NET肯定没有忘记这一点(。
IColorRampPtr
本身就是一个智能指针,您必须使用它,因为您在VC++中使用了#import
生成的.NET类型库。因此,您永远不应该在智能指针上调用Release()
,因为当它超出范围时(或者,如果在类成员中使用,当对象被销毁时(,它会被释放。
如果您想要一个稍后必须调用Release()
的原始指针,请使用原始接口指针(例如IColorRamp*
(或智能指针Detach()
。通常,当接口指针的作用域变得不确定时,您需要一个原始接口指针。如果作用域定义良好,并且可以使用智能指针,请将其保留为智能指针。
来自MSDN(https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.addref%28v=vs.80%29.aspx):
公共语言运行库管理COM的引用计数对象,使其不必直接使用此方法。在里面在极少数情况下,例如测试自定义封送拆收器,您可能会发现手动操作对象的生存期所必需的。打电话后AddRef,必须使用这样的方法来递减引用计数作为Marshal.Release。不要依赖AddRef的返回值,因为它有时可能不稳定。
值得一看吗?
- 将字符串存储在c++中的稳定内存中
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- Win32编译器选项和内存分配
- 当vector是tje全局变量时,c++中vector的内存管理
- 带内存和隔离功能的SQLite
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 迭代时从向量和内存中删除对象
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 为什么示例代码访问IUnknown中已删除的内存
- 如何在C++类内存结构中创建"spacer"?
- Qt对象所有权内存泄漏
- 使shared_ptr失去对内存的所有权
- 给出一个 std::vector 对另一个向量的内存的所有权?
- 使用PYBIND11,如何为Array_t对象设置基础内存的所有权
- 如何从eigen :: matrix获取内存所有权
- 从 Qt 类派生的用户定义类中的内存所有权
- MSXML方法是否对其BSTR参数拥有内存所有权?
- 从C#COM方法返回对象和内存所有权