⚡
zig string 周り
よく?使うものをメモしておく 0.15.2
slice: []const u8
literal
const slice: []const u8 = "abc";
const slice: []const u8 = &.{ 'a', 'b', 'c', 0 };
to pointer
slice.ptr
&slice[0];
c 相互運用
c の関数を呼ぶ
header
const c = @cImport({
@cInclude("stdio.h");
});
c.printf("hello");
定義作成
// extern を付けて body の無い関数を作る
// c_int, c_char など明示的に c である型がある。
// i32, u8 とかでもわりと動く。
extern fn hello(ptr: [*c]const u8) void;
hello("world");
c に関数を公開する
// export つける
export fn hello(ptr: [*c]const u8) void
{
}
c の文字列
c_ptr: [*c]u8
というポインタになる。
このポインタ [*c] は zig の [*], [*:0], ?* あたりの特徴を兼ね備えていて
- nullable
- index アクセス可
- sentinel 0 が期待される
- c_char にせずとも u8 でわりと通る
というような挙動をする。
nullable をはがす
// c_ptr: [*c]const u8
if(c_ptr)|zig_ptr|
{
// zig_ptr: [*]const u8
}
to slice
const slice: []const u8 = std.mem.span(c_ptr);
// 長さが既知
const slice: []const u8 = c_ptr[0..len];
strlen
const len: usize = std.mem.len(c_ptr);
strcmp
test Strcmp {
const c_import = @cImport({
@cInclude("string.h");
});
const Tmp = struct {
fn zigStrcmp(lhs: []const u8, rhs: []const u8) c_int {
return switch (std.mem.order(u8, lhs, rhs)) {
.gt => 1,
.eq => 0,
.lt => -1,
};
}
};
{
const a = "abc";
const b = "bcd";
try std.testing.expectEqual(c_import.strcmp(a, b), Tmp.zigStrcmp(a, b));
}
{
const b = "abc";
const a = "bcd";
try std.testing.expectEqual(c_import.strcmp(a, b), Tmp.zigStrcmp(a, b));
}
{
const a = "abc";
const b = "abc";
try std.testing.expectEqual(c_import.strcmp(a, b), Tmp.zigStrcmp(a, b));
}
}
va_list
var ap = @cVaStart();
defer @cVaEnd(&ap);
_ = c.vsprintf(buf, fmt, @ptrCast(&ap));
Discussion