我有一个与c库(xlib)集成的zig项目.该库有一个方法,需要我将整个argv数组作为参数传递给它.在zig extern定义中,库函数argv参数的预期类型是[*c][*c]u8.

当我运行Linux时,我正在使用非跨平台的方式来获取zig中的MIDI参数

var argv = std.os.argv;

锯齿形参数属于[][*:0]u8类型.我有2个问题.

  1. 将zig vargs铸造/构建为C vargs([][*:0]u8 - [*c][*c]u8)的最务实的方法是什么
  2. [*c][*c]u8到底是什么意思?

我已经很久没有在这么低的水平工作了.我对[*c][*c]u8是c指针列表的理解正确吗,其中每个c指针都是指向空结尾字符串的第一个字符的指针?

推荐答案

将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兼容性而存在.它可以被解除引用和索引.
    • 在c中,所有指针都可以被解除引用和索引:
      int myvalue = 0;
      int* mypointer = &myvalue;
      *mypointer = 1; // allowed
      mypointer[0] = 2; // allowed
      
    • 当将c翻译为zig时,zig不知道c指针是单个项还是array.
    • 这就是为什么它会发出[*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
    • [*c]一个或多个项指针,包含
      • U8

你的解释是正确的.


因为我们知道这些都是数组,所以zig中更好的表示是[*][*:0]U8,一个数组的array.但translate-c不知道这一点,因此它会发出c兼容性指针.

  • [*] unknown-length array pointer containing
    • [*:0] unknown-length 0-sentineled array pointer containing
      • U8

因为我们还知道外部数组的长度(使用argv),所以我们可以将指针[*][*:0]U8和长度usize组合成一个切片:[][*:0]U8.

这就是为什么std.os.argv返回[][*:0]U8.

C++相关问答推荐

为什么已经设置的值在C中被重置为for循环条件中的新值?

GCC不警告隐式指针到整数转换'

找出文件是否包含给定的文件签名

从内联程序集调用Rust函数和调用约定

有没有更简单的方法从用户那里获取数据类型来计算结果

Malloc(sizeof(char[Length]))是否不正确?

正在try 将文件/文件夹名从目录 struct 存储到链接列表

使用GOTO从多个嵌套循环C继续

为什么可以在typedef之前使用typedef d struct 体?

如何将字符串传递给函数并返回在C中更改的相同字符串?

LibpCap禁用监视器模式(C、MacOS)

用C宏替换strncMP函数中的参数

向上强制转换C中的数值类型总是可逆的吗?

CC2538裸机项目编译但不起作用

为 struct 中的数组动态分配内存时出错

C-try 将整数和 struct 数组存储到二进制文件中

将size_t分配给off_t会产生符号转换错误

GCC认为这是一个VLA是对的吗?

在 C 中的 scanf() 格式说明符中使用宏获取字符串长度

C23 中是否有 __attribute__((nonnull)) 的等效项?