DLL调用中的函数指针 - 如何在C#中处理?

时间:2015-05-12 08:45:45

标签: c# dll callback

我正在使用从我的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调用的回调函数?

谢谢!

1 个答案:

答案 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...
    }
}