繁体   English   中英

如何通过IntPtr将C ++数组编组为C#

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM