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

outersky outersky at gmail.com
Mon Nov 5 05:49:14 PST 2007


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 "
:(



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