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

gr1d3r

我正在实现一个C ++ DLL,该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#串行类。我的C ++串行函数运行良好。

uart.Read(void *Buffer, unsigned int MaxNbBytes, unsigned int TimeOut_ms)参考:

\ Buffer:从串行设备读取的字节数组
\ MaxNbBytes:允许读取的最大字节数
\ TimeOut_ms:放弃读取之前的超时延迟

戴维·赫弗南

错误是您对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为match unsigned int当然,使用uint可能会引入多余的演员,您可能会觉得讨厌。int为了方便起见,您很可能会坚持执行p / invoke声明。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章