我知道同样的问题已经讨论过了。 我正在使用.dll库(最初是用C ++编写的,调用约定是stdcall)。我需要的功能描述如下:
function EKSIS_COM_Read(aPortName: PAnsiChar; aPortSpeed: Integer; aID: Integer; aMem: AnsiChar; aAddr: Word; aData: PByte; aCount: Word): Boolean;
bool EKSIS_COM_Read(char[] aPortName, int aPortSpeed, int aID, char aMem, WORD aAddr, BYTE aData, WORD aCount);
参数描述:
aPortName – com-port (example «COM2»);
aPortSpeed –data rate;
aID –device address;
aMem – memory type (I,R,F);
aAddr –register address;
aData – a pointer to the memory address where the reading will be held;
aCount – the number of bytes read.
在使用c#的VS 2013中,我写了以下内容:
[DllImport("EksisExchange.dll", EntryPoint = "EKSIS_COM_Read", CallingConvention = CallingConvention.StdCall)]
public static extern bool Read(char[] aPortName, int aPortSpeed, int aID, char aMem, ushort aAddr, ref float aData,
ushort aCount);
但有时在模拟过程中我感到很恐怖:
System.AccessViolationException。试图读取或写入受保护的内存。
为什么会这样?为什么它有时只会发生?
答案 0 :(得分:0)
[DllImport("EksisExchange.dll", EntryPoint = "EKSIS_COM_Read", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public static extern bool Read(string aPortName, int aPortSpeed, int aID, char aMem, ushort aAddr, byte[] aData, ushort aCount);
您必须将ANSI,以null结尾的字符串传递给该函数。最简单的方法是传递一个字符串,让编组人员完成工作。 aMem
aData
是将读取数据的缓冲区。它必须是缓冲区,例如byte[]
。您在调用方法之前创建。您将缓冲区的大小放在aCount
。
该签名应该与以下内容一起使用:
byte[] buffer = new byte[1024];
bool res = Read("COM1", 19200, 1, 'I', 123, buffer, (ushort)buffer.Length);
请注意,此签名不合逻辑:方法无法返回读取的字节数