在 CFFI 中使用标准库头文件

Using standard library headers with CFFI

我正在使用 Python 和 CFFI 为我用 C 编写的库编写一些单元测试,该库涉及 Linux 上的套接字编程。 .c 文件被编译成共享库,然后使用 ffi.dlopen() 加载。

自然地使用 struct sockaddr_in 结构,它在 netinet/in.h 中定义,在我的例子中,它在另一个结构中使用。

typedef struct sDeviceSockAddr
{
    int sockfd;
    struct sockaddr_in deviceAddr;  
} tDeviceSockAddr;

我正在使用 ffi.cdef() 来定义这个结构。 运行 单元测试 returns 出现(预期的)以下错误:

TypeError: field 'tDeviceSockAddr.DeviceAddr' has ctype 'struct sockaddr_in' of unknown size

我的第一个想法是如何加载整个 netinet/in.h,但作为 CFFI 的新手,我不确定这是要走的路。

是否可以正确加载netinet/in.h?如果是这样,如何? 如果没有,有什么方法可以做到这一点?

如果您使用的是 ffi.dlopen(),那您就不走运了。做到这一点的唯一方法是在你的 cdef 中显式声明结构 sockaddr_in,可能是 Linux headers 的 copy-pasting 位,假设你在 Linux---当然结果是不可移植的。

您可能不想研究使用正确的 ffibuilder 方法,该方法在安装时需要编译器,但允许您使用任何外部包含文件。这是 https://cffi.readthedocs.io/en/latest/overview.html#main-mode-of-usage 中描述的模式。在那种模式下,如果您不需要来自 Python 的结构 sockaddr_in 的内容,您将在 cdef() 中写 struct sockaddr_in { ...; };,字面意思是 dot-dot-dot;或者如果你这样做,你可以包括你需要的字段,但一定要写“...;”,这意味着 "this is a partial declaration; please use the real header to fix the order of fields and total size of the structure".