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

outersky outersky at gmail.com
Mon Nov 5 06:27:46 PST 2007


haha, it works , I'm so happy  :)

thank you!

outersky


Regan Heath 写道:
> 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