Marshal::GetFunctionPointerForDelegate:我应该发布它的结果吗?

问题描述 投票:0回答:3

我正在 C++/CLI 项目中将托管 System.Action 转换为非托管 std::function;使用回调后我应该释放给定的 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?
}
c# lambda c++-cli std-function
3个回答
10
投票

不。 没有 Marshal 类方法可以执行此操作。 与所有动态生成的代码一样,由此方法创建的 thunk 与 AppDomain 关联,并在 AppDomain 卸载时被卸载。

请注意,委托对象的情况并非如此,它受正常的垃圾收集规则的约束。 而且你必须小心,重击并不能让它保持活力。 这是代码中的一个错误,可以在本机代码忙于执行时收集委托。 您需要将此行代码添加到方法的末尾: GC::KeepAlive(callback);

假设只有当 Execute() 方法正在执行时才会进行回调。  如果非托管代码将函数指针存储在该方法调用之外,那么您必须将委托对象存储在某处以保持其有效。  使用 GCHandle.Alloc() 绝对确定(无需固定)。


4
投票
http://msdn.microsoft.com/en-us/library/367eeye0%28v=VS.100%29.aspx


2
投票

© www.soinside.com 2019 - 2024. All rights reserved.