簡體   English   中英

如何將 C 字符串傳遞給需要 Zig 字符串的 Zig 函數?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM