A Zig String literal is a single-item pointer to a null-terminated byte array, which is perfect to be used as a C's char *
String!
However, when I try to use this simple C function from Zig:
int count_bytes(const char *str) {
int count = 0;
while(str[count]) {
count++;
}
return count;
}
Zig caller:
const std = @import("std");
const c = @cImport({
@cInclude("add.c");
});
const testing = std.testing;
test "should be able to count string length" {
try testing.expectEqual(0, c.count_bytes(""));
}
I get this error:
./src/main.zig:16:46: error: expected type '[*c]u8', found '*const [0:0]u8'
try testing.expectEqual(0, c.count_bytes(""));
^
./src/main.zig:16:46: note: cast discards const qualifier
try testing.expectEqual(0, c.count_bytes(""));
^
This article explains about Zig String literals in a similar situation, but I was unable to use the trick to make the String non-const:
test "should be able to count string length" {
var cstr = "".*;
try testing.expectEqual(0, c.count_bytes(&cstr));
}
Result is an even stranger error:
./src/main.zig:17:45: error: expected type 'comptime_int', found 'c_int'
try testing.expectEqual(0, c.count_bytes(&cstr));
^
I also tried casting the String to a C Pointer as shown in the Zig Docs:
test "should be able to count string length" {
var cstr: [*c]u8 = &"".*;
try testing.expectEqual(0, c.count_bytes(cstr));
}
Which also gives an error:
./src/main.zig:16:27: error: expected type '[*c]u8', found '*const [0:0]u8'
var cstr: [*c]u8 = &"".*;
^
./src/main.zig:16:27: note: cast discards const qualifier
var cstr: [*c]u8 = &"".*;
^
How can I do this?
EDIT:
I am getting suggestions that do not work with Zig 0.9, which is the latest stable release as I am writing this.
Please try this out first if you think you know a solution... put the C file at src-c/add.c
, and the Zig file at src/main.zig
,
then run this to try:
zig test src/main.zig -I src-c