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

Function pointer in DLL call - how to handle in C#?

我正在使用从我的 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# 应用程序之外使用这个函数呢?有没有办法定义一个 C# 方法用作此 DLL 调用的回调函数?

谢谢!

您必须声明与本机函数指针匹配的委托类型。它可能应该是这样的:

[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...
    }
}