C#/C++ 回调作为 NULL 传递
Posted
技术标签:
【中文标题】C#/C++ 回调作为 NULL 传递【英文标题】:C#/C++ Callback Passed as 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。
【问题讨论】:
【参考方案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);
【讨论】:
数组不是问题,我已经检查过了。以上是关于C#/C++ 回调作为 NULL 传递的主要内容,如果未能解决你的问题,请参考以下文章