[英]how to marshal c++ array to c# via IntPtr
考虑以下设置:具有C ++库的c#应用程序。 c#元素是通过回调从c ++填充的。 在C#端回调的定义如下:
void callbackTester(IntPtr pData, UInt32 length)
{
int[] data = new int[length];
Marshal.Copy(pData, data, (int)0, (int)length);
//using data.. on c#
}
现在,在c ++方面,回调的定义如下:
typedef void (__stdcall *func)(uint8_t* pdata, uint32_t length);
和C ++使用这样的回调:
void onData()
{
std::vector<uint8_t> dataToCallback;
// fill in dataToCallback
_callback(&(dataToCallback[0]), dataToCallback.size());
// where _callback is a pointer to that c# function
}
我的任务:使用回调从C ++端在C#端获取数组。
因此,当c ++对象调用onData()函数时,它将从c#调用我的回调。 到现在为止还挺好。 我已经制作了一个使用此功能的c ++测试程序,并且我在回调端正确接收了数组。 如果我在C#测试仪上使用它,我会收到废话。
例如:如果我正在发送{1,1}的uint8_t数组,我将为c ++测试器获得{1,1},并且在c#端得到{0xfeeeabab,0xfeeefeee} ...显然,uint8_t *之间的转换C ++指针和IntPtr C#工作不按我的预期。
有什么建议么? 非常感谢。
问题似乎是C ++ uint8_t
是无符号字节,而C# int
是有符号4字节整数。 因此,您有一个简单的类型不匹配。 与uint8_t
匹配的C#类型为byte
。
您的回调应为:
void callbackTester(IntPtr pData, uint length)
{
byte[] data = new byte[length];
Marshal.Copy(pData, data, 0, (int)length);
}
要检查的一件事是,在C#端,您期望每个元素为int-4个字节(“ int []数据”),但是在C ++上,您仅为每个元素分配uint8-1个字节。
调整分配或长度使用情况,您可能会遇到访问冲突,这就是为什么看到魔术字节的原因[1]。
[1] http://en.wikipedia.org/wiki/Magic_number_(编程)#Magic_debug_values
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.