System.AccessViolationException。尝试读取或写入受保护的内存

时间:2015-05-08 07:03:56

标签: c# access-violation

我知道同样的问题已经讨论过了。 我正在使用.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。试图读取或写入受保护的内存。

为什么会这样?为什么它有时只会发生?

1 个答案:

答案 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);

请注意,此签名不合逻辑:方法无法返回读取的字节数