固定一个功能指针

Kri*_*ter 8 c# interop c++-cli

我需要将托管回调传递给非托管TCP接收器.由于它是一个需要在应用程序的生命周期中存在的线程,我需要防止它被垃圾收集.我到处都读到不需要固定函数指针,GCHandle.Alloc将完成阻止垃圾收集的工作.

但这是给定的吗?我已经看到托管此代码的AppPool因访问冲突而崩溃.为什么我不怀疑发生此错误的事实是因为函数指针被垃圾收集了?

这篇文章支持这一事实.

更新:这似乎大大减少了崩溃.这种方法有问题吗?

typedef void (__cdecl *ProcMessageFunc)(void* param, void* paramBuf, ULONG bufSize);
FuncDelegate^ fp = gcnew MessageFuncDelegate(this, &Handler); 
pin_ptr<MessageFuncDelegate^> pinnedFunctionPointer = &fp; 
ret = Receiver ((ProcMessageFunc)pinnedFunctionPointer);
Run Code Online (Sandbox Code Playgroud)

Gov*_*ert 9

我完全按照你的建议做 - GCHandle.Alloc代表但没有固定 - 并且在许多不同的平台和.NET版本2.0上广泛使用没有任何问题 - 4.类似于:

 DelegateHandle = GCHandle.Alloc(xlDelegate);
 FunctionPointer = Marshal.GetFunctionPointerForDelegate(xlDelegate);
Run Code Online (Sandbox Code Playgroud)

FunctionPointer再传递到本机代码,并DelegateHandle保存后清理.

这似乎是最好的参考:http://msdn.microsoft.com/en-us/library/367eeye0(v = vs.80).aspx.

您指向的帖子中没有任何内容与此引用相矛盾 - 您确实需要保护委托免受垃圾收集,这只是不需要固定.

  • 我认为对GetFunctionPointerForDelegate的调用构建了一个具有固定入口点的小编组存根,但如果移动了委托,则存根仍将知道如何调用它.因此导出的函数指针不是委托对象地址的直接导出(与固定数组或结构成员不同).请记住,导出的"本机"功能还必须实现本机 - >托管转换. (2认同)