我正在使用从我的C#应用程序中调用的本机DLL。其中一个DLL函数定义如下:
int set_line(const int width,fct_line_callback callback)
fct_line_callback本身定义为
typedef int (*fct_line_callback)(double power,void *userData);
那么如何从我的C#-application中使用这个功能呢?有没有办法定义一个C#方法用作此DLL调用的回调函数?
谢谢!
答案 0 :(得分:3)
您必须声明与本机函数指针匹配的委托类型。它可能应该是这样的:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate int fct_line_callback(double power, IntPtr userdata);
现在您可以编写pinvoke声明:
[DllImport("foo.dll", CallingConvention = CallingConvention.Cdecl)]
extern static int set_line(int width, fct_line_callback callback);
如果回调只能在执行 set_line()时进行,那么调用本机函数很简单:
public void SetLine(int width) {
set_line(width, MyCallback);
}
private void MyCallback(double power, IntPtr userdata) {
// etc...
}
但是,如果在执行 set_line()之后可以进行回调,换句话说当本机代码存储函数指针时,则必须确保垃圾回收器无法收集委托对象。最简单的方法是将对象存储在 static 变量中:
static class Wrapper {
private static fct_line_callback callback = MyCallback;
public static void SetLine(int width) {
set_line(width, callback);
}
private static int MyCallback(double power, IntPtr userdata) {
// etc...
}
}