澄清 Python CFFI 定义文件中“空”C 结构定义的有效性和原因

Posted

技术标签:

【中文标题】澄清 Python CFFI 定义文件中“空”C 结构定义的有效性和原因【英文标题】:Clarification sought on validity and reason for "empty" C struct definition in Python CFFI definition file 【发布时间】:2021-05-28 18:15:45 【问题描述】:

我正在阅读一些 code,并遇到了这个相当奇怪的 C 结构定义:

typedef struct dataObject
  
      ...;
   DATA_OBJECT;

谁能解释一下(如果可能的话,附上参考资料):

    如果这是一个有效的结构定义。 这样定义的目的是什么(没有定义字段/成员)。

【问题讨论】:

确切地展示了我在代码库中遇到它的方式。就像我说的,这是来自代码源 - verbatim. 我很确定它是伪代码? 那不是C源文件;文件扩展名是.cdef。单看名字,我猜想是其他软件处理成C源文件的东西。 你确定上面提到的代码可以编译吗?命名接受它的编译器! here is the file used , here is doc for FFI.cdef() 并表示:The declarations can also contain “...” at various places; these are placeholders that will be completed by the compiler.。是时候刷一下谷歌技能了。而this doc 我认为解释了语义。 【参考方案1】:

如果这是一个有效的结构定义

没有。

这样定义的目的是什么(没有定义字段/成员)?

该文件的目的是为 python CFFI 解析器提供类型和函数声明以供使用。

此文件的目的是由python CFFI ffibuilder.cdef() 预处理。来自letting C compiler fill the gaps:

此外,您可以在 cdef() 的各个地方使用“...”(字面意思是点-点-点),以要求 C 编译器填写详细信息。这些地方是:

结构声明:任何以“...;”结尾的 struct 或 union 因为最后一个“字段”是部分的:它可能缺少字段,将它们声明为乱序,使用非标准对齐等。确切地说,通过查看 cdef 推断出的字段偏移量、总结构大小和总结构对齐不依赖,而是由编译器更正。 (但请注意,您只能访问您声明的字段,而不能访问其他字段。)任何不使用“...”的结构声明都被认为是准确的,但这是经过检查的:如果不正确,则会出现错误. [...] 未知类型:[....] 在某些情况下,您需要说 foo_t 不是不透明的,而只是一个您不知道任何字段的结构;那么你会使用typedef struct ...; foo_t;

我怀疑这对 CFFI 来说意味着 struct dataObjectDATA_OBJECT 是不透明类型,只能用作指针,并且 CFFI 解析器不支持结构声明。

据我所知,该文件用于here in clips_build.py 构建clipspy 到C 的python 接口。

【讨论】:

这种语法使DATA_OBJECT not 不透明。对于不透明的结构,常规的 C 语法也适用于 cffi。不同之处在于非透明结构具有已知大小并且可以被实例化。一些 C API 就是这样工作的,你调用一个函数来初始化你的结构(而不​​是直接写它的字段),但是结构本身必须由你的代码声明,并且你将一个指向它的指针传递给初始化函数。跨度> 是的,如果结构实际上是不透明的,定义中将没有 typedef,它必须(可选)放在结构前向声明中。【参考方案2】:
    如果这是一个有效的结构定义

不,不是。获取 C17 6.7.2.1 形式语法的一部分:

struct-declaration:specifier-qualifier-list struct-declarator-listopt@ 987654321@static_assert-declaration

因此,首先,该结构需要包含一个“说明符限定符列表”,用简单的英语来说就是变量名之前的const int 等内容。由于这不存在,例如 gcc 会抱怨语法错误:

错误:“...”标记之前的预期说明符限定符列表


2.这样定义的目的是什么(没有定义字段/成员)?

我猜它要么是伪代码,要么是开发者“TODO”,他们提交了无法编译的代码,因为它尚未编写。

【讨论】:

以上是关于澄清 Python CFFI 定义文件中“空”C 结构定义的有效性和原因的主要内容,如果未能解决你的问题,请参考以下文章

在 Python CFFI 中声明包含 time_t 字段的结构

如何使用 Python CFFI 正确包装 C 库

如何使用 cffi 在 C 中嵌入一个返回字符串的 Python 函数?

如何使用 CFFI 将包含其标头的 C 库包装到 python 程序中?

使用 CFFI 在 Python 中创建 CData 类型的缓冲区

为自定义 C 库分发 CFFI 包装器