提问人:Iridium 提问时间:10/26/2023 最后编辑:Iridium 更新时间:10/27/2023 访问量:90
如何使用 PInvoke 将数组指针从 C# 传递到 C 库
How to pass array pointer using PInvoke from C# to C library
问:
我正在用 C# 编写一个软件,它需要从以 dll 形式提供的 C 库中调用一个函数。在这个库中,存在一个名为
getData(uint16_t *buffer, const uint16_t dataIndex)
使用对应于 .buffer
dataIndex
在 C# 中,我尝试了以下方法来调用此函数:
[DllImport(DllPath, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
static private extern int getData(ushort[] buffer, ushort dataIndex);
ushort[] buffer = new ushort[4096];
int response = getData(buffer, 1);
此 comiles 并运行,但缓冲区始终仅包含从 0 到 65535 的随机值。我还尝试添加到DllImport语句中,但它也没有帮助。以前,我编写了一些有效的 C++ 代码来使用此库,但不得不将代码库更改为 C#,因为我被迫使用仅存在于 C# 的库,所以我知道该库有效。[In, Out]
C++ 中的函数调用如下所示:
uint16_t Buffer[4096];
uint Respose = getFrame(Buffer, 1);
我的猜测是类型编组在某种程度上不正确,但我不知道如何正确操作。我研究了 C# 中的类型编组,但我找不到解决问题的方法。
如何使用此库获取数据?有没有另一种选择,也许使用或使用并手动读取和转换该内存地址背后的数据?如何检查传递的内存是否实际被写入?IntPtr
unsafe
答:
-1赞
Mark Benningfield
10/26/2023
#1
如果使用不安全的上下文(通常是与本机代码互操作的最简单方法),则可以使用指向数组第一个元素的指针,这样 GC 就不会移动它。fixed
ushort[] buffer = new ushort[4096];
int response = 0;
unsafe {
fixed (ushort *pbuff = buffer) {
response = getData(pbuff, 1);
}
}
-1赞
Iridium
10/27/2023
#2
我弄清楚了问题出在哪里:我错误地使用了提供的库。由于没有文档,我联系了开发人员,我们能够解决它。数组一直被正确传输和编组,问题出在另一个函数调用上。
评论
[In, Out]
static private extern int getData([In, Out] ushort[] buffer, ushort dataIndex);
buffer[pixelOffset + indexOfPixelInPacket] = pixel