可能有更干净的方法,但以下是我用来使其发挥作用的一些步骤。
定义委托和将其传递给 DLL 的函数。这些参数将被发送回 C# 委托:
public delegate uint CallbackFn( uint param1, uint param2 );
[DllImport("yourdll.dll", CallingConvention=CallingConvention.Winapi, EntryPoint="RegisterTheCallback" )]
private static extern uint RegisterTheCallback( CallbackFn pfn );
创建一个变量来存储委托。确保这不会超出范围。在我的测试中,我发现 GC 会回收它(它没有“意识到”我的 DLL 仍在使用它):
CallbackFn mCmdCallback = null;
然后在某处初始化它:
mCmdCallback = new CallbackFn( YourCallback );
然后将其传递给您的 DLL:
RegisterTheCallback( mCmdCallback );
并定义将接收调用的实际方法:
private uint YourCallback( uint param1, uint param2 )
{
// report progress etc.
}
DLL 中的代码可能如下所示:
DWORD _declspec( dllexport ) WINAPI RegisterTheCallback
(
DWORD (WINAPI *lpfnCallback)( DWORD param1, DWORD param2 )
)
{
// Store lpfnCallback somewhere so that it can be called later
...
}
然后 DLL 中的代码可以在需要时使用适当的数据调用它:
ret = (lpfnCallback)( 234, 456 );