c# - 将字节数组从 C++ DLL 返回到 C#

标签 c# c++ dllimport dllexport

我正在实现一个需要将数据读/写到串行线路的 C++ DLL。 此 DLL 的用法是在 C# 应用程序中。 目前我无法在使用 C++ 读取代码时设法从 C# 应用程序读取数据(没有 C# 包装器,读取功能可以正常工作)。

C++代码:

extern "C" __declspec(dllexport) int Read(void *Buffer, unsigned int MaxNbBytes, unsigned int TimeOut_ms)
{
    return uart.Read(Buffer, MaxNbBytes, TimeOut_ms);
}

C#代码

[DllImport("RS232LIB.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
public static extern int Read(out byte[] bytesRead, int maxNbBytes, int timeOutMs);

var bytes = new byte[4];
Read(out bytes, 4, 10);

运行这些行后,我不断收到 System.AccessViolationException。 我该如何解决这个问题?

备注:我不能使用 C# Serial 类。我的 C++ 串行函数运行良好。

uart.Read(void *Buffer, unsigned int MaxNbBytes, unsigned int TimeOut_ms)引用:

\Buffer : array of bytes read from the serial device
\MaxNbBytes : maximum allowed number of bytes read
\TimeOut_ms : delay of timeout before giving up the reading

最佳答案

错误是您使用了 out 关键字。如果您需要被调用者分配一个新数组并将其返回给您,就会使用它。这是一个额外的间接级别。

因此您可以使用以下 p/invoke:

[DllImport("RS232LIB.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int Read(byte[] bytesRead, uint maxNbBytes, uint timeOutMs);

这样调用它:

var bytes = new byte[4];
Read(bytes, (uint)bytes.Length, timeOutMs);

注意 byte 是 blittable,所以 byte[] 也是 blittable。这意味着该框架将简单地固定您的阵列。因此它编码为 [In,Out]。如果您想更明确地说明您可以编写的意图:

[DllImport("RS232LIB.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int Read([Out] byte[] bytesRead, uint maxNbBytes, uint timeOutMs);

但行为不会有任何不同。该数组仍将被固定,并且从语义上讲,该参数将为 [In,Out]

我还删除了不必要的 CharSet 规范,并将其他两个参数更改为 uint 以匹配 unsigned int。当然,使用 uint 可能会引入额外的转换,您可能会觉得这很烦人。为了方便起见,您可能会在 p/invoke 声明中坚持使用 int

关于c# - 将字节数组从 C++ DLL 返回到 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49294534/

相关文章:

c# - 未分配的不可空变量的值 (C#)

c++ - 如何初始化具有 const 变量的结构数组

c++ - 编译qemu-xen时signal.c出错

c++ - 清除内存块(或 SDL 表面)的最快方法是什么?

c# - DllImport 返回空终止字符串 AccessViolationException

c# - 我怎样才能投出一个集合

c# - ASP MVC - 使用时区和文化处理日期时间本地化

c# - 从另一个线程捕获 Application.ThreadException 中的错误

C++加载两个版本的Qt5GUI.dll

c++ - 错误: function definition is marked dllimport