Is there an easy to call c functions with char** parameters?

Regan Heath regan at netmail.co.nz
Mon Nov 5 05:28:52 PST 2007


outersky wrote:
> Hi all ,
> I'm new to c and d.
> 
> Now I don't know how to call c function with char** parameters.
> And when I call c function with char* parameters, I need to invoke
> std.string.toStringz()
> to do some transform.
> but about char** ?

It depends a little on what the C function is doing with the char** but
in general I expect it is assigning something to the pointer.  Maybe
it's allocating memory eg.

[some.c]

func(char **p) { *p = strdup("test"); }

void main()
{
  char *p;
  func(&p);
  printf("%s", p);
}

or perhaps it's using it as a continuation like a custom thread safe
strtok might do...

char *strtok(char *start, char *tok, char **next)
{
  //perform tok
  *next = upto;  //assign next to the place we are upto
}

in either case something is assigned to the pointer (which is why it
needs a pointer to it).

If you want to convert the resulting pointer into a D array you might do
the following:

char[] arr;
char *p;
func(&p);
arr = p[0..strlen(p)];

I don't think this works:

char[] arr;
func(&arr.ptr);
arr.length = strlen(arr.ptr);

because arr.length would be 0 and setting a new length would trigger a
re-allocation.

Which brings me to the problem you need to be aware of in the case where
func allocates memory.  You should not assign the resulting point to
arr.ptr either directly or via the assignment using a slice shown above
because when the array tries to reallocate it does so on a memory block
it didn't allocate in the first place, and this is very likely to fail.

Instead a safe alternative is to wrap the C function call, copy the
data, and free the memory allocated in C using whatever method the C
library provides eg.

void dfunc(ref char[] arr)
{
  char *p;
  func(&p);
  arr.length = strlen(p);
  arr[] = p[0..arr.length];
  func_free(&p);
}

Regan

p.s. some casts may be required implmenting the above in D 2.0 due to
invariant/const etc.

p.p.s if the C function is returning data in a character set which is
not plain ASCII or UTF-8 then it may result in invalid UTF-8 being
stored in the D array.


More information about the Digitalmars-d-learn mailing list