澄清 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 dataObject
和 DATA_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 字段的结构
如何使用 cffi 在 C 中嵌入一个返回字符串的 Python 函数?
如何使用 CFFI 将包含其标头的 C 库包装到 python 程序中?