Tom
Tom

Reputation: 3044

How to translate C++ char** to Delphi?

I have a C++ DLL:

int __stdcall Hello(int numFiles, char **inFiles)

and I don't know how to translate this char **. I tried:

function Hello(numFiles: Integer; InFiles: PPChar): Integer; stdcall; external 'dll2.dll';

and then:

    Files: array of PChar;
begin
   SetLength(Files, 2);
   Files[0] := PChar('siema.jpg');
   Files[1] := PChar('siema2.jpg');

   c := Hello(2, @Files[0]);

but all I get is "Access violation"

Upvotes: 1

Views: 2180

Answers (1)

David Heffernan
David Heffernan

Reputation: 613511

On the face of it, given the information in the question, your code seems basically fine. However, a rookie mistake, made by many beginners with interop, is to believe that a function's signature is enough to define the interface. It is not. For instance, a parameter of type char** could be used for many different things. So, to specify the information you must also specify the semantics of the parameters, not just the syntax.

Given

int __stdcall Hello(int numFiles, char **inFiles)

let us assume the following:

  • The return value is an error code, with 0 indicating success.
  • The first parameter is the number of files.
  • The second parameter is an array of files, of length specified by the first parameter. Each element of the array is a C string, a pointer to a null-terminated array of 8 bit characters.

With those assumptions in place, I would write the code like this:

function Hello(numFiles: Integer; InFiles: PPAnsiChar): Integer; stdcall;
  external 'dll2.dll';

The function would be called like this:

var
  Files: array of PAnsiChar;
  retval: Integer;
....
SetLength(Files, 2);
Files[0] := PAnsiChar('siema.jpg');
Files[1] := PAnsiChar('siema2.jpg');
retval := Hello(Length(Files), PPAnsiChar(Files));
if retval <> 0 then
  ... handle error

You might prefer to write the final parameter as @Files[0] if you prefer. I prefer the cast because it allows me to pass an empty array even when range checking is enabled.

Note that I used PAnsiChar to match with char*. The PChar type is an alias to either PAnsiChar or PWideChar depending on the Delphi version. It is better to be explicit.

Of course, my assumptions may be wrong. You should confirm them by consulting the library's documentation.

Upvotes: 6

Related Questions