#What's the best way to cast array to C pointer?
1 messages · Page 1 of 1 (latest)
Why do you want to do this?
Because C api takes pointer
You can pass eg. *[16][*:0]const u8 to a function that accepts [*c][*c]const u8
It'll implicitly coerce
Let me try to understand this syntax...
Firstly what type is your array?
It's const char**, so in my case [16]*const u8
Is that the type you've written in Zig?
Because if it's an array of C strings, that's not the correct type
const char** is the C type I am trying to target
*const u8 points to a single u8, not a sequence of u8
I am not sure what Zig type I should use
Sure; I'm asking about the Zig types
But [16]*const u8 should point to 16 C strings, right?
No, it's an array of 16 pointers to singular u8
You should use [16][*:0]const u8 for 16 pointers to 0-terminated sequences of u8 (which is what a C string is)
It says error: expected type '[*c][*c]const u8', found '[16][*:0]const u8'
You need to ref it, you're currently passing the array itself rather than a pointer to it
Then I get error: expected type '[*c][*c]const u8', found '*[16][*:0]const u8' instead
hmm, that should work
If you want to look at a bigger snippet:
var n_exts: c_uint = undefined;
var extensions: [16][*:0]const u8 = undefined;
if (c.SDL_Vulkan_GetInstanceExtensions(window, &n_exts, &extensions) != c.SDL_TRUE) {
@panic("Failed to get required extensions");
}
Ohh ofc, the error note explains the issue
Because it's a mutable pointer type, the function could modify the array and add null pointers
So it has to be a [16]?[*:0]const u8
Nope: error: expected type '*[*:0]const u8', found '*[16]?[*:0]const u8'
src/renderer.zig:32:49: error: expected type '*[*:0]const u8', found '*[16]?[*:0]const u8'
const instance = try VkInstance(n_exts, &extensions);
Right, it's a different place
btw functions shouldn't start with capital letters in Zig :)
(unless they return types)
Hmmm, I thought Zig style guide says if it returns a type it should be TitleCase
Sure, but that function doesn't
It's a constructor?
It returns a vk.Instance I would assume
Ah, I understand the confusion
Wait, do you mean returning a "type" not an "instance"?
Yes
I mean if the return type is literally type
(which is how generics work in Zig :)
Are there any good explanation of pointer types in Zig?
BTW, [*c] is a bit awkward to type
Is it required? Or can it be implicitly cast in some case?
You almost never need to write [*c] in your own code
It's designed for use by translate-c and nothing else
The docs have a decent reference: https://ziglang.org/documentation/master/#Pointers
For the [*:0] syntax: https://ziglang.org/documentation/master/#Sentinel-Terminated-Pointers
So what should this function definition be without [*c]?
fn createVkInstance(n_exts: c_uint, exts: [*c][*c]const u8) !c.VkInstance
I tried quite a few variations of arrays and pointers, but none compile
fn createVkInstance(n_exts: c_uint, exts: [*][*:0]const u8) !c.VkInstance (assuming it can't put null pointers into exts)
Ah, I got this one to work [*]?[*:0]const u8
But if you're writing a nice Zig wrapper, use fn createVkInstance(exts: [][*:0]const u8) !c.VkInstance
If it can put nulls in exts then []?[*:0]const u8
wdym by "doesn't work"?
only with a cast
But what is the error?
The reason I suggest []?[*:0]const u8 is because it gets rid of the extra n_exts arg
But it needs some tweaks inside the function
/opt/homebrew/Cellar/zig/HEAD-06e9b2c_1/lib/zig/std/mem.zig:461:65: error: expected type '[*c]const [*c]const u8', found '[]?[*:0]const u8'
@field(value, field.name) = @field(init, field.name);