Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从C#COM方法返回对象和内存所有权_C#_C++_.net_Com - Fatal编程技术网

从C#COM方法返回对象和内存所有权

从C#COM方法返回对象和内存所有权,c#,c++,.net,com,C#,C++,.net,Com,我在C#中实现了一个COM组件: 我从C++中称之为: IColorRampPtr colorRamp; { ColorRamps::IColorRampsPtr colorRamps(ColorRamps::CLSID_ColorRamps); HRESULT hr = colorRamps->getColorRamp(&colorRamp); colorRamp.AddRef(); // Should I do this?? } 起初,我没有AddR

我在C#中实现了一个COM组件:

我从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++中调用这样的函数时,我用函数来做AddReFor(),并将内存所有权传递给调用方。C#COM不是这样吗

我没有在ColorRamps.getColorRamp()中调用Marshal.AddRef()。

来自MSDN():

公共语言运行库管理COM的引用计数 对象,因此无需直接使用此方法。在里面 极少数情况下,例如测试自定义封送拆收器,您可能会发现它 手动操作对象的生存期所必需的。打完电话 AddRef,必须使用以下方法减少引用计数 作为元帅,释放。不要依赖AddRef的返回值,因为它 有时可能不稳定


值得一看吗?

最有可能发生这种情况的原因是您
释放了(
指针),而不是.NET在返回之前忘记了
AddRef()
(提示:.NET肯定没有忘记这一点)

icolorAmptr
本身就是一个智能指针,您必须使用它,因为您需要在VC++中使用.NET生成的类型库。因此,永远不要在智能指针上调用
Release()
,因为当它超出范围时(或者,如果在类成员中使用,当对象被销毁时),它将被释放


如果您想要一个原始指针,以后必须在其上调用
Release()
,请使用原始接口指针(例如
icoloramp*
)或。通常,当其范围变得不确定时,需要原始接口指针。如果范围定义得很好,并且可以使用智能指针,请将其保留为智能指针。

我确信我不会释放()指针。由于它是一个智能指针,我认为它应该自行处理。我遇到的崩溃可能来自代码中的其他地方,但事实是,当我调用AddRef()时,我无法重现它。我认为纯虚拟函数调用异常可能来自运行时可调用包装器?
virtual HRESULT __stdcall getColorRamp(/*[out,retval]*/ struct IColorRamp * * pRetVal ) = 0;