Search code examples
c++delphidelphi-10.1-berlin

How do call C++ function through Delphi wrapper


My first question here. Please give me a hint if I do something wrong.

My question: I have to call a c++ function through a Delphi wrapper (VCL). The delphi wrapper looks like:

function TFoxBurnerSDK.ReadFileContents(FilePath: string; Offset: int64; var Buffer; Length: integer; var ActualLength: integer): boolean;
begin
    CheckActive;
    if FSessionHandle=nil then begin
        FLastError:=BS_SDK_ERROR_BAD_REQUEST;
        Result:=false;
        Exit;
    end;
    Result:=DLLResult(FoxBurnerSDKCore.ReadFileContents(FSessionHandle,
      PFoxSDKChar(FoxSDKString(FilePath)), Offset, @buffer, Length, @ActualLength));
end

How to call this function from Delphi code. Mean what var/parameter I will need to send to the function? It seems that buffer and ActualLength are pointers in C++

int32 BS_CALL ReadFileContents( HSESSION hSession, const TCHAR* lpszFilePath, int64 nOffset, void* pBuffer, int32 nBufferSize, int32* pRead );

And that is the problem for me, how to handle the pointers in Delphi. I thought that this is the right call in Delphi:

procedure TForm1.Button1Click(Sender: TObject);
var Bytes: TBytes;
iRead : integer;
begin
SetLength(Bytes, 2352*27);
iRead:=0;

Burner.ReadFileContents('\autorun.inf', 0, Bytes, 2352*27, iRead);

end; 

But this will cause a memory expection. If I call the function from a C++ sample it works well. Just here in Delphi an expection happen. So I think I made something wrong.

I hope I gave all needed information to get an answer. If not please let me know what I miss. Thank you.

Added information: Definition:

ReadFileContents : function (Session: HSESSION; FilePath: PFoxSDKChar; Offset: int64; Buffer: pointer; BufferSize: integer; Read: pinteger): integer; stdcall; 

function ReadFileContents(FilePath: string; Offset: int64; var Buffer; Length: integer; var ActualLength: integer): boolean;

Solution

  • It should be defined this way:

    ReadFileContents: function
    ( Session: HSESSION  // HSESSION
    ; FilePath: PChar  // TCHAR*
    ; Offset: Int64  // int64
    ; Buffer: Pointer  // void*
    ; BufferSize: Integer  // int32
    ; Read: PInteger  // int32*
    ): Integer;  // int32
    cdecl;  // C++, don't know why you use stdcall
    

    And the call should be

    var
      iResult, iLength, iRead: Integer;
      sFilePath: String;
      iOffset: Int64;
      aBuf: Array of Byte;
    begin
      iLength:= 5;
      SetLength( aBuf, iLength );
      iResult:= ReadFileContents( FSessionHandle, PChar(sFilePath), iOffset, @aBuf[0], iLength, @iRead );