www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - DLL: (const char *paramNames[],size_t numParams)

reply Andre Pany <andre s-e-a-p.de> writes:
Hi,

I need to call a C function within a DLL which has following 
signature:
   void GetParamNames (const char *paramNames[], size_t numParams);

The purpose of this function is to return a list of texts
I defined in D:
extern(C) GetParamNames (const char[]* paramNames, size_t 
numParams);

Is this correct? How can I call the function? I tried several 
possibilities but
always get a runtime crash.

Kind regards
André
Jul 09 2018
parent reply Basile B. <b2.temp gmx.com> writes:
On Monday, 9 July 2018 at 10:33:03 UTC, Andre Pany wrote:
 Hi,

 I need to call a C function within a DLL which has following 
 signature:
   void GetParamNames (const char *paramNames[], size_t 
 numParams);

 The purpose of this function is to return a list of texts
 I defined in D:
 extern(C) GetParamNames (const char[]* paramNames, size_t 
 numParams);

 Is this correct? How can I call the function? I tried several 
 possibilities but
 always get a runtime crash.

 Kind regards
 André
Hi, no it's not correct i think, right translation would be extern(C) void GetParamNames(const char** paramNames, size_t numParams); If you use the D array syntax you'll get into troubles because of ABI i think. Baz.
Jul 09 2018
next sibling parent reply Andre Pany <andre s-e-a-p.de> writes:
On Monday, 9 July 2018 at 10:38:54 UTC, Basile B. wrote:
 On Monday, 9 July 2018 at 10:33:03 UTC, Andre Pany wrote:
 Hi, no it's not correct i think, right translation would be

     extern(C) void GetParamNames(const char** paramNames, 
 size_t numParams);

 If you use the D array syntax you'll get into troubles because 
 of ABI i think.

 Baz.
Thanks, it seems I also have to allocate the pointer before with the numbers of numParams. In python the code looks s.th. like this self.output_names = (c_char_p * self.number_outputs)() Do you know that is the equivalent in D? Kind regards André
Jul 09 2018
next sibling parent reply Andre Pany <andre s-e-a-p.de> writes:
On Monday, 9 July 2018 at 10:56:18 UTC, Andre Pany wrote:
 On Monday, 9 July 2018 at 10:38:54 UTC, Basile B. wrote:
 On Monday, 9 July 2018 at 10:33:03 UTC, Andre Pany wrote:
 Hi, no it's not correct i think, right translation would be

     extern(C) void GetParamNames(const char** paramNames, 
 size_t numParams);

 If you use the D array syntax you'll get into troubles because 
 of ABI i think.

 Baz.
Thanks, it seems I also have to allocate the pointer before with the numbers of numParams. In python the code looks s.th. like this self.output_names = (c_char_p * self.number_outputs)() Do you know that is the equivalent in D? Kind regards André
If found this working, is this OK, or do I have a memory bug here? import core.stdc.stdlib: malloc, free; string[] result; size_t numOutputs = 4; const(char**) arr = cast (const(char**)) malloc(numOutputs * (char*).sizeof); auto status = GetParamNames(arr, numOutputs); for(int i = 0; i < numOutputs; i++) { const(char*) c = arr[i]; result ~= c.fromStringz.dup; } free(cast(void*) arr); Kind regards André
Jul 09 2018
parent Kagamin <spam here.lot> writes:
         const(char)*[] znames;
         znames.length=4;
         GetParamNames(znames.ptr, znames.length);
         const char[][] names=znames.map!fromStringz.array;
Jul 09 2018
prev sibling parent reply Basile B. <b2.temp gmx.com> writes:
On Monday, 9 July 2018 at 10:56:18 UTC, Andre Pany wrote:
 On Monday, 9 July 2018 at 10:38:54 UTC, Basile B. wrote:
 On Monday, 9 July 2018 at 10:33:03 UTC, Andre Pany wrote:
 Hi, no it's not correct i think, right translation would be

     extern(C) void GetParamNames(const char** paramNames, 
 size_t numParams);

 If you use the D array syntax you'll get into troubles because 
 of ABI i think.

 Baz.
Thanks, it seems I also have to allocate the pointer before with the numbers of numParams. In python the code looks s.th. like this self.output_names = (c_char_p * self.number_outputs)() Do you know that is the equivalent in D? Kind regards André
you don't need to allocate but to retrieve each string, do something like this: foreach(i; 0 .. numParams) { string p = fromStringz(paramNames + i) } although i have a doubt for pointer arithmetic. Maybe it should be incremented by i * size_t.sizeof since char.sizeof is 1. Maybe someone else will be more helpful here. Baz.
Jul 09 2018
parent reply Basile B. <b2.temp gmx.com> writes:
On Monday, 9 July 2018 at 11:10:01 UTC, Basile B. wrote:
 On Monday, 9 July 2018 at 10:56:18 UTC, Andre Pany wrote:
 On Monday, 9 July 2018 at 10:38:54 UTC, Basile B. wrote:
 On Monday, 9 July 2018 at 10:33:03 UTC, Andre Pany wrote:
 Hi, no it's not correct i think, right translation would be

     extern(C) void GetParamNames(const char** paramNames, 
 size_t numParams);

 If you use the D array syntax you'll get into troubles 
 because of ABI i think.

 Baz.
Thanks, it seems I also have to allocate the pointer before with the numbers of numParams. In python the code looks s.th. like this self.output_names = (c_char_p * self.number_outputs)() Do you know that is the equivalent in D? Kind regards André
you don't need to allocate but to retrieve each string, do something like this: foreach(i; 0 .. numParams) { string p = fromStringz(paramNames + i) } although i have a doubt for pointer arithmetic. Maybe it should be incremented by i * size_t.sizeof since char.sizeof is 1. Maybe someone else will be more helpful here. Baz.
Ok, i've read your other answers and it seems that you have a way to test so i think you'll figure it out yourself, but you don't need to alloc. Once the fromStringz verified to be good maybe dup/idup in case the C lib free the stuff but that's all.
Jul 09 2018
parent Andre Pany <andre s-e-a-p.de> writes:
On Monday, 9 July 2018 at 11:39:46 UTC, Basile B. wrote:
 Ok, i've read your other answers and it seems that you have a 
 way to test so i think you'll figure it out yourself, but you 
 don't need to alloc. Once the fromStringz verified to be good 
 maybe dup/idup in case the C lib free the stuff but that's all.
Thanks a lot for your help. Kind regards André
Jul 09 2018
prev sibling parent reply Kagamin <spam here.lot> writes:
Correct signature:
extern(C) void GetParamNames(const(char)** paramNames, size_t 
numParams);
In C const applies only to the nearest member.
Jul 09 2018
parent Andre Pany <andre s-e-a-p.de> writes:
On Monday, 9 July 2018 at 13:48:05 UTC, Kagamin wrote:
 Correct signature:
 extern(C) void GetParamNames(const(char)** paramNames, size_t 
 numParams);
 In C const applies only to the nearest member.
Thank you, that looks great. Kind regards Andre
Jul 09 2018