通过 NativeCall 在 Raku 中使用 void 结构

Using void structs in Raku via NativeCall

我正在尝试 link libzip 到 Raku,它使用 void struct 或没有主体的结构,如下所示:

struct zip;
typedef struct zip zip_t;

我在我的 Raku 程序中以同样的方式声明它:

class zip_t is repr('CStruct'){};

这失败了:

Class zip_t has no attributes, which is illegal with the CStruct representation.

我发现该错误的唯一参考是 MyHTML 中的 in this non-addressed issue。这可能会使它成为一种倒退,但我真的不确定。有什么想法吗?

一个google for "no attributes, which is illegal with the CStruct representation" yields three matches. The third leads to the following recent bug/change for module LibZip:

- class zip is repr('CStruct') is export { }
+ class zip is repr('CPointer') is export { }

在我发布这篇文章之前,我看到 Curt Tilmes 发表了类似的评论。


我对 C 知之甚少。但我喜欢研究事物。这个答案是一个猜测和一些基于谷歌搜索的笔记。

  • 您引用的错误消息是关于 NativeCall 的,这反过来意味着它是关于 Rakudo 编译器的,而不是 Raku 语言。 (我想你知道这一点,对于许多人和情况来说,区别通常并不重要,但我认为在这种情况下值得注意。)

  • google for "empty struct" is Empty structs in C 的最佳 SO 匹配。该问题询问空结构的语义并将它们与外语一起使用。这个问题及其答案似乎很有用;接下来的几点是基于他们的摘录。

  • "Structures with no named members [have undefined behavior]"。我想说这解释了为什么您会收到 NativeCall 错误消息 ("no attributes, which is illegal with the CStruct representation")。 NativeCall 是关于拥有一个可靠的 C 可移植接口,因此它大概必须立即拒绝未定义的方面。 (也许错误消息会提示该怎么做?可能不会。最好有人必须搜索消息的匹配项,就像您所做的那样。然后大概他们会看到这个 SO。)

  • 我假设您只是想 绑定 与 libzip 的空结构作为来回传递数据的一部分,而不读取或写入数据。我怀疑这是问题的症结所在;鉴于 NativeCall(相当合理)拒绝以通常的方式进行绑定,您如何绑定?

  • "From the point of view of writing [a foreign language] binding to a C library ... You're never going to do anything with objects of the [empty struct] type except pass them to imported C functions." 我认为这对您的情况是正确的,并且根据 C 规范,其他任何行为都是未定义的行为,因此至少与 C 库的特定 C 编译器相关联和用于编译 Rakudo 的 C 编译器,即使在那时也很可能未定义。我想 Curt 已经问过你的用法,以防绑定正在做或需要一些疯狂的事情,但我非常怀疑它是。