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

Regan Heath regan at netmail.co.nz
Mon Nov 5 06:14:24 PST 2007


outersky wrote:
> Thank you, thank you very much.
> 
> Sorry for  unclear expression of my question,
> 
> I'm now trying to write a simple program as:
> 
> main.d   :
> 
>     extern(C) void printargv(char* argv[], int count);
>     int main(char[][] argv){
>         printargv(cast(char* [])argv,argv.length);
>         return 0;
>     }
> 
> func.c  :
> 
> void printargv(char* argv[], int count){
>     for(int i=0; i<count; i++){
>         printf("%d:%s\n", argv[i]);
>     }
> }
> 
> 
> gcc -g -c -std=gnu99 func.c
> dmd -g main.d func.o
> ./main arg1 arg2
> 
> and result in
> " core dumped "
> :(

Ahh.. I see.

The first problem is that the C code:
  printf("%d:%s\n", argv[i]);

needs to be:
  printf("%d:%s\n", i, argv[i]);

:)

The next problem you have is that char[][] in D is an array of arrays,
meaning that in memory you have an array of structures which resemble this:

struct array {
  void *ptr;
  int length;
}

So, if you have:

char[][] argv;
argv.length = 4;

then argv itself looks like
  [ptr:length]

and argv.ptr would point to a memory location which looks like:
  [ptr:length][ptr:length][ptr:length][ptr:length]

and each of those ptr's point to the actual char data.

When you call:
  printargv(cast(char* [])argv,argv.length);

you pass the ptr of the argv array to the C function which tries to
treat it like a char** and fails miserably.

Instead what you actually need to do is build a C style array of char*
pointers and pass that, try something like...

char **buildCargs(char[][] argv)
{
  char **res;

  //does (char*).sizeof work?
  res = malloc(argv.length * (char*).sizeof);

  foreach(i, arg; argv)
    res[i] = arg.ptr

  return res;
}

and call it like:

printargv(buildCargs(argv), argv.length);

You'll need to find the import required to use malloc i.e. std.c.stdlib?

I don't have a D compiler handy to make sure this actually works, or is
even syntactically valid but hopefully it's close enough that you can
figure it out.

Regan


More information about the Digitalmars-d-learn mailing list