将回调参数从 C# 传递到非托管 C++

Posted

技术标签:

【中文标题】将回调参数从 C# 传递到非托管 C++【英文标题】:Pass callback argument from C# to unmanaged C++ 【发布时间】:2014-07-16 08:17:51 【问题描述】:

我有一些非托管 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

我的方法完全错了吗?

【问题讨论】:

为什么回调 ref 在你的 extern 方法中? 【参考方案1】:

这是因为您必须将 ref 修饰符放在参数之前,这会迫使它成为一个变量。所以:

将你的外部更改为:

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

您的电话:

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

更新:如果你想将参数传递给回调(比如一个 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);

【讨论】:

如果回调有参数呢?有什么特点吗? 它可以正常工作。只需定义您的委托以匹配该委托并将属性放在参数上以指定非托管类型。要我更新代码吗?

以上是关于将回调参数从 C# 传递到非托管 C++的主要内容,如果未能解决你的问题,请参考以下文章

将多维数组从托管代码传递到非托管代码

如何使用 C++/CLI Wrapper 将变量参数从托管传递到非托管?

将 DataTable 传递给非托管环境(visual c# 2005)

使用 ATL/COM 将托管字节 [] 转换为非托管字节数组

将数组从非托管 C++ 传递到 C#

通过引用从 c# 将 char** 传递给非托管 C++