【问题标题】:C#/C++ Callback Passed as NULLC#/C++ 回调作为 NULL 传递
【发布时间】:2014-12-02 14:32:58
【问题描述】:

我在将回调函数从 C# 传递到 C++ 非托管 DLL 时遇到了一些问题。运行程序时,DLL 接收 NULL 而不是回调。

回调函数定义为

typedef void(__cdecl *CallbackFunction)();

C++ 函数定义为

__declspec(dllexport) void __cdecl StreamData(unsigned char *Buffer, unsigned int BufferSize, unsigned long Points,
 unsigned short AveragingPower, CallbackFunction BufferUpdated);

C# 回调和函数委托定义为

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void BufferUpdatedCallback();

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void StreamDataDelegate(byte[] Buffer, uint BufferSize, ulong Points,
 ushort AveragingPower, BufferUpdatedCallback BufferUpdated);

C++ 函数确实可以正常工作,因为我已经从 C++ 控制台应用程序对其进行了测试,并且它可以正常工作。在 C# 中,我可以通过Marshal.GetFunctionPointer(Delegate d) 获取回调委托的指针,但是当我在程序进入 StreamData 函数时单步执行程序时,指针在 DLL 中变为 NULL。 DLL 和 C# 委托的调用约定是一致的。

我错过了一些非常基本的东西吗?有人知道解决问题的方法吗?

更新

如果 unsigned long Points 参数从 DLL 和 C# 中删除,则函数正常工作,否则回调为 NULL。

【问题讨论】:

    标签: c# c++ c dll callback


    【解决方案1】:

    C++ 编译器中的 unsigned long 是 32 位整数类型。但是,您声明为 ulong,一种 64 位类型。这导致的参数未对齐使委托在 C++ 代码中看起来像 NULL,它正在读取该 ulong 变量的高 32 位。

    您必须在 Points 参数的 [DllImport] 声明中使用 uint

    【讨论】:

      【解决方案2】:

      试试这个:

      私有委托 void StreamDataDelegate(ref byte[] Buffer, uint BufferSize, ulong Points, ushort AveragingPower, BufferUpdatedCallback BufferUpdated);

      【讨论】:

      • 数组不是问题,我已经检查过了。
      猜你喜欢
      • 1970-01-01
      • 2016-10-08
      • 1970-01-01
      • 2017-03-09
      • 1970-01-01
      • 2013-04-12
      • 1970-01-01
      • 2021-02-23
      • 1970-01-01
      相关资源
      最近更新 更多