Reputation: 3044
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
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:
0
indicating success.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