user401247
user401247

Reputation:

What is the Delphi declaration for char***

I have a C based DLL that exports a function that has char*** as an argument, this is a pointer to a pointer to a pointer of char (Non-unicode) My question is, after much frustration, what is the equivalent declaration at the Delphi end?

I've tried for example:

 // C Method declaration
 void method (char*** arg)


 TArrayOfPAnsiChar = array of PAnsiChar;
 PArrayOfPAnsiChar = ^TArrayOfPAnsiChar;
 PPArrayOfPAnsiChar = ^PArrayOfPAnsiChar;

 // Delphi declaration
 procedure method (var p : PPArrayOfPAnsiChar); cdecl;

 p : PPArrayOfAnsiChar;
 method (p)

But I'm not getting anything sensible back. Any suggestions? The var in the declaration is of course already a pointer so perhaps that's where I am going wrong. I've tried many variants, written down on paper what the structure is and reverse engineered a Delphi declration but to no avail. This DLL is used in other C based applications so I assume its functioning correctly.

Using XE6

Upvotes: 1

Views: 807

Answers (2)

David Heffernan
David Heffernan

Reputation: 613511

In this case char*** is a pointer to a pointer that points to an array where each element points to a string.

This implies that the callee is returning data to the caller. So you want to use:

procedure method(out Arg: PPAnsiChar); cdecl; external dllname;

where PPAnsiChar is ^PAnsiChar. Note that PPAnsiChar is defined in the System unit.

The C code has three levels of indirection. The outermost is how function passses data from callee to caller. That's represented as a Delphi out parameter. The remaining two levels of indirection are captured in PPAnsiChar. Finally C's char is an 8 bit type on Windows and so maps to AnsiChar.

You will also need to iterate over the array when the function returns. Like this:

var
  StrArr: PPAnsiChar;
  Str: string;
....
method(StrArr);
while StrArr^ <> nil do
begin
  Str := StrArr^;
  Inc(StrArr);
end;

I'm assuming that the length of the array is indicated by a terminating null pointer. If instead you are told the length, you use a for loop as should be obvious.

Upvotes: 1

Zo&#235; Peterson
Zo&#235; Peterson

Reputation: 13332

Don't use array of, because that declares a dynamic array, and use AnsiChar rather than Char, since the latter is two bytes in Delphi.

PPAnsiChar = ^PAnsiChar;
PPPAnsiChar = ^PPAnsiChar;

procedure Method(Arg: PPPAnsiChar); cdecl;

or

procedure Method(var Arg: PPAnsiChar); cdecl;

If you want to index into the variable like an array, add {$POINTERMATH ON} before declaring the types

Upvotes: 10

Related Questions