将zig vargs转换/构建为C vargs([][*:0]U8 - [*c][*c]U8)的最实用方法是什么
@ptrCast
切片上的.ptr
属性:
const argv = std.os.argv;
const c_ptr: [*c][*c]U8 = @ptrCast(argv.ptr);
(我认为这里不需要指针转换-它应该能够隐式转换argv.ptr
,但它拒绝隐式转换指针子)
[*c][*c]U8到底是什么意思?/我对[*c][*c]U8是c指针列表的理解正确吗,其中每个c指针都是指向空结尾字符串的第一个字符的指针?
Z字形指针有点令人困惑.存在具有不同选项和相似语法的指针、切片和值数组:
*U8
:指向U8值的指针.可以取消引用(value.*
)但不能编入索引(value[0]
)
[*]U8
:指向U8值的未知长度多项指针.可以索引但不能解除引用.
[*c]U8
:一个或多个项指针类型,仅为C兼容性而存在.它可以被解除引用和索引.
[]U8
:一个切片,它是一个指针和一个长度.它类似于struct {ptr: [*]U8, len: usize}
.它可以被索引,但不能被解除引用.
[N]U8
:值数组类型.这不是指针,尽管它看起来像指针.
未知长度的指针和切片可以具有哨兵值.[:0]U8
指定切片在最后一个项(slice[slice.len] == 0
)后面有0
.[*:0]U8
指定虽然长度未知,但数组最后一项后面的项应为0
.
常规指针和未知长度指针都可以隐式转换为c兼容性指针.
现在,来回答这个问题
[*c]
one or many item pointer containing
你的解释是正确的.
因为我们知道这些都是数组,所以zig中更好的表示是[*][*:0]U8
,一个数组的array.但translate-c
不知道这一点,因此它会发出c兼容性指针.
[*]
unknown-length array pointer containing
[*:0]
unknown-length 0
-sentineled array pointer containing
因为我们还知道外部数组的长度(使用argv),所以我们可以将指针[*][*:0]U8
和长度usize
组合成一个切片:[][*:0]U8
.
这就是为什么std.os.argv
返回[][*:0]U8
.