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

Vla*_*tin 1 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;
Run Code Online (Sandbox Code Playgroud)

这是我的dll函数的标头:

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

Mar*_*ort 5

有各种各样的错误。

  1. 首先&在Delphi中意味着不同。您可能想要@。
  2. 但是您不需要,因为您声明了VAR值。
  3. 但是,然后再次声明它们为指针(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;
Run Code Online (Sandbox Code Playgroud)