I’m trying to use a C function from Zig, and the function has a parameter with a type like this: char const * const * When I imported the header file into Zig it became [c*]const [*c]const u8. Now I want to initialize an array with values (string literals) and pass it to this function. But when I try something like this:
I think in general you shouldn’t have variables with raw [*c] types. It’s best to use the more specific Zig pointer types and just let them coerce/cast to and from the raw C types at the point of calling the C API.
If your sub-arrays are null-terminated C style strings then the correct type to construct would be:
// @TypeOf(ptr) = *const [2][*:0]const u8
const ptr = &[_][*:0]const u8{ "foo", "bar" };
// this type can coerce to [*c]const [*c]const u8
const cptr: [*c]const [*c]const u8 = ptr;
Also, you can pass the slice.ptr field to c-style pointers too if you need to get from a slice to a direct pointer. A little different than your example, but still handy.
That works, but now I’m trying to wrap my head around why, specifically what the & is for. In my mind this is creating something closer to char*** in C-world, even though the function is asking for something more like char**.
In declaration foo: [10]T, foo is the entire array, &foo is the address of the array (a pointer).
When you call bar(foo) you pass the entire array by value (not always, zig can optimize this call).
When you call bar(&foo) you pass by value the pointer to the array.
Adding useful related information to solved help topics is good.
We just don’t want discussions to go totally off topic instead of just creating a new topic for it, when it doesn’t really match what was the main discussion.