LoadLibrary并定义对C DLL的回调(函数指针)

时间:2012-09-07 14:42:16

标签: c#

我在DLL中有这样的代码:

int (*callback)(int a, int b);
void mainfunc()
{
    callback(1, 2);
    callback(3, 4);
}

要从C程序访问此DLL,我曾经这样做:

#include <windows.h>

int callback(int a, int b) {return a+b;}

int main()
{
    HANDLE dll = LoadLibrary("test.dll");
    *(void**)GetProcAddress(dll, "callback") = (void*)callback;
    ((void(*))GetProcAddress(dll, "mainfunc"))();
    FreeLibrary(dll);
}

DLL仍然是C代码,但主程序已切换到C#。如何处理函数指针?该代码将如何在C#中?

1 个答案:

答案 0 :(得分:3)

callback是dll中的全局变量,因此您无法[1]从c#设置它。

您也不应该从C设置它。如果回调真的是共享的话,你应该拥有的是SetCallback( MyCallbackType callback )这样的函数来设置它。

但可能,您希望将该函数传递给mainfunc。

在任何一种情况下,这在C#中都很容易做到:

// C#
public delegate Int32 Callback( Int32 a, Int32 b );
[DllImport("test.dll")]
static extern void mainfunc( Callback callback );
// Or if you're setting the callback globally, 
[DllImport("test.dll")]
static extern void SetCallback(Callback callback);
[DllImport("test.dll")]
static extern void mainfunc();

带回家的消息是DllImport足够聪明,可以将具有合理接近签名的委托转换为C函数指针。

[1]好的,所以你可以...... dll注射有时会使用这些线条中的一些黑客,但在任何其他情况下这都是错误的方法。