如何在Zig 0.9中正确将字符串字面量传递给C函数
Zig 0.9 调用C函数传入字符串字面量编译错误解决
问题背景
Zig字符串字面量是指向以null结尾的字节数组的单项指针,理论上完全适配C语言的char *字符串类型,可直接传入使用。但在Zig 0.9稳定版中调用如下简单C函数时,会触发编译错误。
C函数实现:
int count_bytes(const char *str) { int count = 0; while(str[count]) { count++; } return count; }
初始Zig调用代码:
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("")); }
编译报错信息:
./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("")); ^
已尝试的无效方案
方案1:网传去const技巧
修改代码尝试去除字符串const属性:
test "should be able to count string length" { var cstr = "".*; try testing.expectEqual(0, c.count_bytes(&cstr)); }
触发新的编译错误:
./src/main.zig:17:45: error: expected type 'comptime_int', found 'c_int' try testing.expectEqual(0, c.count_bytes(&cstr)); ^
方案2:显式转换为C指针
尝试将字符串显式转为C指针:
test "should be able to count string length" { var cstr: [*c]u8 = &"".*; try testing.expectEqual(0, c.count_bytes(cstr)); }
依然报const丢弃错误:
./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 = &"".*; ^
错误根因
所有方案失败的核心原因有两点:
- C函数参数为
const char *,对应Zig侧的类型是[*c]const u8而非可变的[*c]u8,将const指针强转为可变指针会违反Zig的const校验规则,被编译器直接拦截 std.testing.expectEqual要求两个入参类型完全一致,C函数返回值为c_int类型,直接传入的字面量0是comptime_int类型,类型不匹配会触发校验错误
正确实现
将字符串显式转换为[*c]const u8类型,同时将比较用的字面量0显式声明为c_int类型即可,代码如下:
const std = @import("std"); const c = @cImport({ @cInclude("add.c"); }); const testing = std.testing; test "should be able to count string length" { const c_str = @ptrCast([*c]const u8, ""); try testing.expectEqual(@as(c_int, 0), c.count_bytes(c_str)); }
验证方式
按如下目录结构存放文件:
- C函数文件存放路径:
src-c/add.c - Zig调用文件存放路径:
src/main.zig
执行如下命令即可运行测试并顺利通过:
zig test src/main.zig -I src-c
内容的提问来源于stack exchange,提问作者Renato
相关产品推荐
相关产品推荐

