将C#中的回调参数传递给非托管C ++

时间:2014-07-16 08:17:51

标签: c# c++ marshalling

我有一些非托管C ++动态库和C#GUI应用程序,使用它。我想在一些库提供的方法中通过参数传递回调。是否可以从C#传递回调到非托管C ++方法。

// unmanaged C++
typedef uint8_t (__stdcall *SomeCallback)();

MYDLL_API uint8_t someMethod(SomeCallback cb);

我正试图以这种方式使用库:

// C# part
public delegate Byte SomeDelegate();

[DllImport("mylibraryname.dll")]
public static extern Byte someMethod(ref SomeDelegate pDelegate);

// actuak callback
Byte myCallback() {
    // some code
}

...

// call unmanaged passing callback
static void Main(string[] args) {          
    someMethod(myCallback);
}

我收到编译错误:

 cannot convert from 'method group' to 'ref SomeDelegate

我的方法完全错了吗?

1 个答案:

答案 0 :(得分:2)

这是因为你必须在参数之前加上ref修饰符并强制它成为一个变量。这样:

将你改为:

public static extern Byte someMethod([MarshalAs(UnmanagedType.FunctionPtr)] 
                            ref SomeDelegate pDelegate);

并致电:

        SomeDelegate action = new SomeDelegate(myCallback);
        someMethod(ref action);

UPDATE:如果你想将一个参数传递给回调(比如一个int):

public delegate Byte SomeDelegate([MarshalAs(UnmanagedType.I4)] int value);

[DllImport("mylibraryname.dll")]
public static extern Byte someMethod([MarshalAs(UnmanagedType.FunctionPtr)]
                                       ref SomeDelegate pDelegate);

Byte MyMethod([MarshalAs(UnmanagedType.I4)] int value)
{
    return (byte) (value & 0xFF);
}

并致电:

SomeDelegate action = new SomeDelegate(MyMethod);
someMethod(ref action);