I think one of the most important things is to understand the difference between arrays and pointers in Zig.
In Zig, arrays are value types, not pointer types. This means that e.g. [5]u8
takes up 5 actual bytes of memory, and, in your example, [2053]u8
is a value made up of 2053 bytes of memory.
For pointers, the language reference does a good job of explaining the different pointer types, and notes that slices (which are also a pointer, but carry an associated length, too) should generally be preferred in Zig code.
When working with C from Zig, my general advice would be to use sentinel-terminated slices on the Zig side (e.g. [:0]u8
or [:0]const u8
; many standard library functions will have a Z
suffixed function that will give you a sentinel-terminated result, e.g. std.fs.path.joinZ
, etc) and then you can pass those as sentinel-terminated pointers when calling into C functions that expect null-termination. Note that string literals are already pointers to sentinel terminated arrays (*const [N:0]u8
), so you can pass them directly to C functions without issue (e.g. your_c_function("foo");
).