我有一些 DLL 文件。它包含一些名称为“ABSDefaultCallback”的方法。所以我像这样分配这个方法。
IntPtr hMod = LoadLibrary("bsgui.dll");
IntPtr pAddr = GetProcAddress(hMod, "ABSDefaultCallback");
op.Callback = pAddr;
它正在完美地工作。但我想调用我自己的方法,除了“ABSDefaultCallback”之外,名称是“Callback”。我试着这样做。
DELEGATE_TestFunc fred = new DELEGATE_TestFunc(Callback);
void* pfred = Marshal.GetFunctionPointerForDelegate(fred).ToPointer();
op.Callback = (IntPtr)pfred;
但是这个并不能完美地工作。如何解决我的问题?
最佳答案
我假设您对通过 p/Invoke 所做的一切都具有正确的签名。如果您不这样做,那么您需要先解决这个问题。
根据 this article ,您可能遇到了您的委托(delegate)被垃圾回收的问题。
他们使用 GCHandle.Alloc
在委托(delegate)上创建一个不会被垃圾收集的引用。
static void DemonstrateCallBack_With_GCHandle()
{
var callback_delegate = new CallBack(CallBackFunction);
GCHandle gch = GCHandle.Alloc(callback_delegate);
IntPtr intptr_delegate =
Marshal.GetFunctionPointerForDelegate(callback_delegate);
PerformActionWithCallBack(intptr_delegate);
gch.Free();
}
如果这对你有用,我建议你包装 GCHandle.Alloc
和 gch.Free
在实现 IDisposable
的对象中,并可能考虑使用 SafeHandle
.
这篇文章可能会提供一些相关的细节:http://obiwanjacobi.blogspot.com/2007/05/robust-pinvoke-for-windows-midi-api.html
关于c# - 如何从委托(delegate)获取 C# 函数中的地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7911841/