我应该释放它的结果吗?

本文关键字:结果 释放 我应该 | 更新日期: 2023-09-27 18:13:33

我正在转换一个托管系统。对c++/CLI项目中非托管std::函数的操作;我应该释放给定的IntPtr使用回调后,还是它是不必要的?

void MyClass::Execute(System::Action^ callback)
{           
    IntPtr callbackPtr = Marshal::GetFunctionPointerForDelegate(callback);
    std::function<void (void)> nativeCallback = static_cast<void (__stdcall *) (void)>(callbackPtr.ToPointer());
    m_nativeObject->Execute(wrappedCallback);
    // should I release callbackPtr here?
}

我应该释放它的结果吗?

No。没有Marshal类方法可以做到这一点。像所有动态生成的代码一样,由该方法创建的代码与AppDomain相关联,并在AppDomain被卸载时被卸载。

请注意,这不是委托对象的情况,它受正常的垃圾收集规则的约束。你必须要小心,不能让保持活力。这是代码中的一个bug,委托可以在本机代码忙于执行时被收集。您需要将这行代码添加到方法的末尾:

GC::KeepAlive(callback);

假设回调只会在Execute()方法正在执行时进行。如果非托管代码在此方法调用之外存储函数指针,则必须将委托对象存储在某个地方以保持其有效。

不,但是如果你调用Alloc来在回调委托上创建一个GCHandle,你必须使用GCHandle. free()释放该句柄。这里有一篇很好的文章,包括如何防止GC过早地处置你的委托:http://msdn.microsoft.com/en-us/library/367eeye0%28v=VS.100%29.aspx

不需要释放指针。你已经有了指向函数的指针(这是一个32/64位的大小,取决于你的机器架构)。如果。net框架基础设施需要更多的东西来运行指针,那么所有方法都将是相同的,因此它将被静态分配(无状态)。