C#/ C ++回调传递为NULL

时间:2014-12-02 14:32:58

标签: c# c++ c dll callback

我在将回调函数从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#委托中是一致的。

我错过了一些非常基本的东西吗?有没有人知道纠正这个问题的方法?

更新

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

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:0)

试试这个:

  

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