简体   繁体   English

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

[英]how to marshal c++ array to c# via IntPtr

consider following setup: c# application with c++ library. 考虑以下设置:具有C ++库的c#应用程序。 c# elements are filled from c++ via callback. c#元素是通过回调从c ++填充的。 on c# side callback is defined like this: 在C#端回调的定义如下:

void callbackTester(IntPtr pData, UInt32 length)
{
    int[] data = new int[length];
    Marshal.Copy(pData, data, (int)0, (int)length);
    //using data.. on c#
}

now, on c++ side callback is defined like this: 现在,在c ++方面,回调的定义如下:

typedef void (__stdcall *func)(uint8_t* pdata, uint32_t length);

and c++ is using callback like this: 和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
}

my task: get array from c++ side on c# side using callback. 我的任务:使用回调从C ++端在C#端获取数组。

so, when c++ object is calling onData() function, it calls my callback from c#. 因此,当c ++对象调用onData()函数时,它将从c#调用我的回调。 so far so good. 到现在为止还挺好。 i have made a c++ tester program, which uses this, and i am receiving array correctly on callback side. 我已经制作了一个使用此功能的c ++测试程序,并且我在回调端正确接收了数组。 if i am using it on c# tester, i am receiving crap. 如果我在C#测试仪上使用它,我会收到废话。

for example: if i am sending uint8_t array of {1, 1}, i am getting {1, 1} for c++ tester, and i am getting {0xfeeeabab, 0xfeeefeee} on c# side... obviously, the conversion between uint8_t* c++ pointer and IntPtr c# is working not as i expect. 例如:如果我正在发送{1,1}的uint8_t数组,我将为c ++测试器获得{1,1},并且在c#端得到{0xfeeeabab,0xfeeefeee} ...显然,uint8_t *之间的转换C ++指针和IntPtr C#工作不按我的预期。

any suggestions? 有什么建议么? thanks a lot. 非常感谢。

The issue appears to be that C++ uint8_t is an unsigned byte, and C# int is a signed 4 byte integer. 问题似乎是C ++ uint8_t是无符号字节,而C# int是有符号4字节整数。 So you have a simple mismatch of types. 因此,您有一个简单的类型不匹配。 The C# type that matches uint8_t is byte . uint8_t匹配的C#类型为byte

Your callback should be: 您的回调应为:

void callbackTester(IntPtr pData, uint length)
{
    byte[] data = new byte[length];
    Marshal.Copy(pData, data, 0, (int)length);
}

one thing to check is that on C# side you are expecting int-4 bytes per element ("int[] data") but on C++ you only allocating uint8-1 byte per element. 要检查的一件事是,在C#端,您期望每个元素为int-4个字节(“ int []数据”),但是在C ++上,您仅为每个元素分配uint8-1个字节。

adjust the allocation or length usage, you could be getting access violation, that why you see magic bytes [1]. 调整分配或长度使用情况,您可能会遇到访问冲突,这就是为什么看到魔术字节的原因[1]。

[1] http://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_debug_values [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