www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to Deify char**

reply WhatMeWorry <kheaser gmail.com> writes:
I'm weak enough with C pointers, but when I see char** my brain 
freezes up like a deer caught in headlights. Can anyone translate 
the below C call into D?



ALURE_API const ALCchar** ALURE_APIENTRY 
alureGetDeviceNames(ALCboolean all,ALCsizei *count)

// my poor attempt to Deify it

int count;
const char[][] allDevice = alureGetDeviceNames(true, &count);

// and the inevitable error

alure_stuff.d(190): Error: cannot implicitly convert expression 
((*alureGetDeviceNames)(cast(byte)1, & count)) of type char** to 
const(char[][])



Thanks. (And I have been staring at docs for hours)
May 17 2016
parent ag0aep6g <anonymous example.com> writes:
On 05/17/2016 09:37 PM, WhatMeWorry wrote:
 I'm weak enough with C pointers, but when I see char** my brain freezes
 up like a deer caught in headlights. Can anyone translate the below C
 call into D?
First things first: char** is a perfectly fine D type, of course. But you probably know that.
 ALURE_API const ALCchar** ALURE_APIENTRY alureGetDeviceNames(ALCboolean
 all,ALCsizei *count)

 // my poor attempt to Deify it

 int count;
 const char[][] allDevice = alureGetDeviceNames(true, &count);
char[][] is quite different from char**. While you can make a char[] from a char* by slicing the pointer, you can't make a char[][] from a char** in the same way, because the element type changes. You need to make the char* -> char[] conversions individually and fill a new array with them: ---- import std.stdio: writeln; import std.string: fromStringz; void main() { /* Step 1: Get the char** and the count. */ int count; char** pp = alureGetDeviceNames(&count); /* Step 2: char** + count -> char*[] */ char*[] pa = pp[0 .. count]; /* Step 3: Iterate over the char*[] and convert the elements to char[]. Fill a newly allocated char[][] with them. */ char[][] aa = new char[][](count); foreach (i, p; pa) { char[] a = fromStringz(p); /* char* -> char[] */ aa[i] = a; } /* print to verify */ writeln(aa); /* ["foo", "bar", "baz"] */ } char** alureGetDeviceNames(int* count) { /* just some test data */ *count = 3; return ["foo\0".dup.ptr, "bar\0".dup.ptr, "baz\0".dup.ptr].ptr; } ---- Note that this allocates a new array. Depending on the exact scenario, it may be worthwhile to stop at the char*[] stage instead, and work with null terminated strings.
May 17 2016