sockets - 将标准库头文件与 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
?如果是这样,如何?如果没有,有什么方法可以做到这一点?
解决方案
如果您正在使用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()
或者如果你这样做,你可以包含你需要的字段,但一定要写“ ...;
”,这意味着“这是一个部分声明;请使用真正的标题来固定字段的顺序和结构的总大小”。
推荐阅读
- amazon-web-services - AWS SAM 可以管理哪些服务?
- spring - Spring Cloud 数据流本地服务器 Jar - java.lang.NoClassDefFoundError
- tensorflow - 获取经过训练的 Keras 模型的 logits
- c# - 比较两个数据表并获得差异
- javascript - 添加 getElementById 语句后,警报在 Javascript 中停止工作
- .net - PowerShell 程序集
- r - 用制表符替换空格
- php - 检查日期是否在 PHP 中的多维数组中的多个日期范围之间
- python - 将图像拆分为 N 个图像,其中 N 是其上出现的颜色数
- python - Automatic scaling of y axis in Dash according to the relayoutData attribute