Thread overview
DLL: (const char *paramNames[],size_t numParams)
Jul 09, 2018
Andre Pany
Jul 09, 2018
Basile B.
Jul 09, 2018
Andre Pany
Jul 09, 2018
Andre Pany
Jul 09, 2018
Kagamin
Jul 09, 2018
Basile B.
Jul 09, 2018
Basile B.
Jul 09, 2018
Andre Pany
Jul 09, 2018
Kagamin
Jul 09, 2018
Andre Pany
July 09, 2018
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é
July 09, 2018
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.
July 09, 2018
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é
July 09, 2018
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é

July 09, 2018
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.
July 09, 2018
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.
July 09, 2018
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é
July 09, 2018
        const(char)*[] znames;
        znames.length=4;
        GetParamNames(znames.ptr, znames.length);
        const char[][] names=znames.map!fromStringz.array;
July 09, 2018
Correct signature:
extern(C) void GetParamNames(const(char)** paramNames, size_t numParams);
In C const applies only to the nearest member.
July 09, 2018
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