如何通过 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,我得到 {1, 1} 用于 C++ 测试器,我在 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
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 数组索引的值没有增加
- 将对象数组的引用传递给函数
- 为char数组调整zlib-zpipe
- 2D数组来自文本输入,中间有空格
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- 使用strcpy将char数组的元素复制到另一个数组
- 使用指针从C++中的数组中获取最大值
- C++使用整数的压缩数组初始化对象
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '