如何通过 IntPtr 将 C++ 数组封送到 C#
本文关键字:数组 C++ 何通过 IntPtr | 更新日期: 2023-09-27 17:57:16
请考虑以下设置:具有 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