首页 > 解决方案 > 将标准库头文件与 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()用来定义这个结构。运行单元测试会返回(某种预期的)以下错误:

TypeError:字段 'tDeviceSockAddr.DeviceAddr' 的 ctype 'struct sockaddr_in' 大小未知

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

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

标签: socketspython-cffi

解决方案


如果您正在使用ffi.dlopen(),那么您就不走运了。这样做的唯一方法是在你的 cdef 中显式声明 struct sockaddr_in,可能通过复制粘贴 Linux 头文件的位,假设你在 Linux 上——当然结果是不可移植的。

您可能不想考虑使用适当的ffibuilder方法,这在安装时需要编译器,但允许您使用任何外部包含文件。这是https://cffi.readthedocs.io/en/latest/overview.html#main-mode-of-usage中描述的模式。在那种模式下,如果你不需要 Python 中的 struct sockaddr_in 的内容,你可以用字面点-点-点写struct sockaddr_in { ...; };在 中;cdef()或者如果你这样做,你可以包含你需要的字段,但一定要写“ ...;”,这意味着“这是一个部分声明;请使用真正的标题来固定字段的顺序和结构的总大小”。


推荐阅读