【发布时间】:2018-03-15 08:24:59
【问题描述】:
我正在实现一个需要将数据读/写到串行线路的 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 : 从串行设备读取的字节数组
\MaxNbBytes : 允许读取的最大字节数
\TimeOut_ms : 放弃读取前的超时延迟
【问题讨论】:
-
我不认为这是你的问题,但在 C++ 部分你使用
unsigned int- C# 对应部分不应该使用uint? -
这不是这里的问题。即使我将硬编码值设置为长度和超时,我也遇到了这个异常。
-
我想,你会发现这篇文章的答案很有帮助:stackoverflow.com/questions/15862983/…
-
那个 C++ 函数写得很好,它实际上并没有返回一个数组。它使用您传递的数组并用字节填充它。您必须删除
out。传递 bytes.Length 作为第二个参数,这样你就永远不会出错。并且不要忽略返回值,它可能会告诉您它复制到数组中的字节数。 -
阅读您的 cmets 后,我将
uint签名更改为int并删除了out。也不例外,但我正在从线路中获取垃圾数据。
标签: c# c++ dllimport dllexport