【发布时间】:2014-04-08 13:36:36
【问题描述】:
考虑以下设置:带有 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# 之间的工作不符合我的预期。
有什么建议吗?非常感谢。
【问题讨论】:
-
据我所知 uint8_t != (C#)int.正确的应该是字节。 std::vector 也不是一个数组,我怀疑你可以像这样将它复制到 C#。
-
@floele 你在正确和错误的地方混在一起。 int!=uint8_t, int 是一个 32 位整数。 C# 中的
byte[]可以工作。 std::vector 的底层数据结构是一个数组,因此可以正常工作。提示:使用 std::vector.data 代替 &(dataToCallback[0])。 -
uint8_t 被“投射”到 IntPtr 而不是 UIntPtr,因为 Marshal.Copy 只接受 IntPtr。你还能如何在 c# 端获取数据?
-
@etwas77 C# 中的 IntPtr 用词不当,它实际上等同于 c++
void*。它只是一个内存位置。 -
首先,您要做的是通过 C# 函数的函数指针从 C++ 调用 C# 函数?
标签: c# c++ pinvoke marshalling