我需要将托管回调传递给非托管TCP接收器。由于它是一个需要在应用程序的生命周期中存在的线程,我需要防止它被垃圾收集。我到处都读到不需要固定函数指针,GCHandle.Alloc将完成阻止垃圾收集的工作。
但这是给定的吗?我已经看到托管此代码的AppPool因访问冲突而崩溃。为什么我不怀疑发生此错误的事实是因为函数指针被垃圾收集了?
这post支持这一事实。
更新: 这似乎大大减少了崩溃。这种方法有问题吗?
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);
答案 0 :(得分:8)
我完全按照你的建议去做 - 代理上的GCHandle.Alloc但没有固定 - 并且在许多不同的平台和.NET版本2.0上广泛使用没有任何问题 - 4.类似的东西:
DelegateHandle = GCHandle.Alloc(xlDelegate);
FunctionPointer = Marshal.GetFunctionPointerForDelegate(xlDelegate);
然后将FunctionPointer
传递给本机代码,并保留DelegateHandle
以供稍后清理。
这似乎是最好的参考:http://msdn.microsoft.com/en-us/library/367eeye0(v=vs.80).aspx。
你指出的帖子中没有任何内容与此引用相矛盾 - 你需要保护委托免受垃圾收集,只是固定不是必需的。