为什么从dll调用函数并使用record时会出现访问冲突?

时间:2019-04-03 14:05:31

标签: delphi dll

我尝试调用一个函数以从c ++ dll中读取一些字节。我声明了函数的头,但是当我调用并尝试将数组值分配给记录值时,函数在MSVCR80.dll中返回访问冲突。 这是我的代码,如果我使用valueBits记录,则返回AV,如果我使用一个简单的布尔变量,它将起作用。我需要一个建议。

    function TdmCustom.CheckBon(var valueBits: TStatusPrintingRecord): Boolean;
    var cmd          : String;
    //valueBit     : array[0..10] of AnsiChar;
    MemArea      : PAnsiChar;
    pdwByteRead  : LPDWORD;
    lpdwSysError : LPDWORD;
    aNrComanda   : String;
    Arr          : array of AnsiChar;
begin
  pdwByteRead  := 0;
  lpdwSysError := 0;
  aNrComanda   := '1011';
  cmd        := Format('%S',[aNrComanda]);
  SendCommandToPrinter(cmd,True);
  lastError := CEFReadB(MemArea, &pdwByteRead, &lpdwSysError)//acess violation if i use valueBits record
  SetLength(Arr, Integer(pdwByteRead));
  Move(MemArea^, Arr[0], Integer(pdwByteRead));
  if lastError = 0 then begin
    valueBits.S8_isBonFiscalDeschis   := Arr[8] = '1';
    //valueBits.S9_isBonNefiscalDeschis := Arr[9] = '1';
  end;
  Result := lastError = 0;
end;

这是我的dll函数的标头:

function CEFReadB(lpMemArea : PAnsiChar; var pdwByteRead : LPDWORD; var lpdwSysError : LPDWORD) : DWORD; cdecl; external DLLName name 'CEFReadCustom' delayed;

1 个答案:

答案 0 :(得分:5)

有各种各样的错误。

  1. 首先&在Delphi中的含义有所不同。您可能需要@。
  2. 但是您不需要,因为您声明了VAR。
  3. 但是您再次将它们声明为var(LPdw *)指针。将它们声明为VAR会吃掉一个间接值,因此在声明中,类型可能只是DWORD。
  4. 在将内存传递给函数之前,可能还需要为内存分配内存
  5. 并传递以字节读取方式分配的数量。

我试图进行清理,并提出了以下未经测试的代码。如果您需要更多帮助,请使用C ++声明和用法更新您的帖子。

function CEFReadB(lpMemArea : PAnsiChar; var byteRead : DWORD; var lpdwSysError : DWORD) : DWORD; cdecl; external DLLName name 'CEFReadCustom' delayed;

function TdmCustom.CheckBon(var valueBits: TStatusPrintingRecord): Boolean;
var cmd          : String;

    MemArea      : ansistring;
    LastError    : DWORD;
    ByteRead     : DWORD;
    SysError     : DWORD;
    aNrComanda   : String;

begin
  byteRead  := 50;
  setlength(memarea,byteread);
  lpdwSysError := 0;
  aNrComanda   := '1011';
  cmd        := Format('%S',[aNrComanda]);
  SendCommandToPrinter(cmd,True);
  lastError := CEFReadB(pansichar(MemArea), byteRead, SysError);
  if lasterror= 0 then  
    begin
      setlength(memarea,byteRead);
      if byteread>=9 then
        begin
         valueBits.S8_isBonFiscalDeschis   := Arr[8] = '1';   // note 8 and 9 are 1-based!
         valueBits.S9_isBonNefiscalDeschis := Arr[9] = '1';
        end
      else 
        exit(False); // not enough data read.
    end; 

  Result := lastError = 0;
end;