You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 16:57:20