#How to convert from *[]const u8 to [*c]const [*c]const u8
1 messages ยท Page 1 of 1 (latest)
var c_src = [_][*:0]const u8{src.ptr};
var c_len = [_]i32{ @intCast(i32, src.len) };
c.glShaderSource(shad, 1, &c_src, &c_len);
(or just use zgl which handles this for you :)
I will definitely use zgl, but there is something I want to explore while learning zig. So it is not a final product, is something I want to struggle with while learning zig ๐
There is no need to put everything into an array as both pointer to arrays and single item pointers can coerce to c pointers.
Here is how I would do it:
const source_len = @intCast(c_int, source.len);
c.glShaderSource(shader, 1, &source.ptr, &source_len);
Thank you both very much! I did not know single item pointers can coerce to c pointers.
Is there some nice schema of some sort of mappings between zig and c?
No need for the explicit type annotation on sourceLen (also that should be source_len according to zig style guide)
And no, you don't need to put it in arrays, but it's good practice since what OpenGL is expecting is a multi-pointer, not a single-pointer
While C doesn't have a distinction between those, Zig does, so it's nice to have it be the correct types on the Zig side rather than relying on C's unsafe conversions :)
They're both fine ways to do it, as long as you understand what's going on :)
I prefer the explicitness of arrays since it also allows you to provide more than one source string if you want to, which is what the API is designed to do
Exactly why I love the two different approaches
cool
Thank you both!
error: expected type '[*:0]const u8', found '[*]const u8'
var c_src = [_][*:0]const u8{file_vertex.data.ptr};
the :0 is the termination right?
just change the array decl to be [_][*]const u8
in this case you don't need null termination, because you're also passing the length
though, you may still want to consider ensuring you're using null terminated strings in the general case, in case you ever don't pass a length for whatever reason
but that can be a bridge crossed another time
I marked it down in my Todo list and learning list. In the end I definitely want to both understand and compile, but in that order.
well, just as a brief: ensuring null termination can be in done in a number of ways.
The most primitive way is to just assert that a sequence of bytes is null terminated, and ask the type system to make it so, by doing slice[0.. :0]. This will panic in safe modes if slice doesn't end with 0, and is UB in unsafe modes.
The former is usually only done after an operation that creates or modifies slice, such that it would be null-terminated. E.g., reallocating the slice with an added 0 at the end, and then sentinel-slicing it.
The most frequently-used method is to use a function that does the former two for you, e.g. std.mem.Allocator.dupeZ
oops yeah, forgot this case doesn't need null termination :)
Thank you so much for the infos