[英]How to pass a C string into a Zig function expecting a Zig string?
嘗試使用需要字符串的 Zig 庫...但我從 C 庫中獲得了字符串緩沖區。
這意味着我需要將[*c]u8
類型的值傳遞給接受[:0]const u8
的函數。
怎么做?
到目前為止,我發現了這種方式:
const buffer: [*c]u8 = callC();
const str = std.mem.span(@ptrCast([*:0]const u8, buffer));
哪個看起來比它應該的更復雜(並制作副本??)。
Zig 文檔說:
字符串字面量是指向 u8 的以 null 結尾的數組的 const 指針。
所以我認為它們是兼容的 C 字符串,並且像@as([*:0]const u8, buffer)
這樣的非常簡單的轉換就足夠了?
哪個看起來比它應該的更復雜(並制作副本??)。
所以我認為它們是兼容的 C 字符串,並且像 @as([*:0]const u8, buffer) 這樣的非常簡單的轉換就足夠了?
這里的問題是[*:0]u8
和[:0]u8
之間存在差異
[*:0]u8
是一個以0
結尾的未知大小的指針。 要確定它的長度,您必須遍歷它並找到它的結束位置。[:0]u8
是一個包含指針和長度的切片。 你可以把它想象成struct {ptr: [*:0]u8, len: usize}
。 這允許使用它的代碼立即知道它的長度,而不必循環它。 @pointerCast
不需要從[*c]u8
轉換為[*:0]u8
:
const std = @import("std");
test "convert c string to [*:0]u8" {
const c_string: [*c]const u8 = "some c string";
const as_ptr: [*:0]const u8 = c_string;
_ = as_ptr;
}
要獲得 zig 樣式的字符串切片( []const u8
或[:0]const u8
),您可以使用標准庫函數std.mem.span (ptr):
const std = @import("std");
test "convert c string to zig string" {
const c_string: [*c]const u8 = "some c string";
const as_slice: [:0]const u8 = std.mem.span(c_string);
try std.testing.expectEqualStrings(as_slice, "some c string");
}
const buffer: [*c]u8 = callC(); const str = std.mem.span(@ptrCast([*:0]const u8, buffer));
哪個看起來比它應該的更復雜(並制作副本??)。
std.mem.span
不會復制字符串 - 沒有標准庫函數會復制某些內容,除非您將其傳遞給分配器。
它所做的是計算字符串的長度,然后返回相同內存的切片,這次包括長度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.