【发布时间】:2017-11-24 09:46:18
【问题描述】:
我正在尝试使用 ctypes 模块通过 Python 单元测试框架对 C 代码进行单元测试。我使用 GCC 和 Linux。被测C文件(packet.c)有一个头文件(packet.h),如下:
#ifndef PACKET_H
#define PACKET_H
void byte_received(char b);
void packet_received_callback(int length, char *packet);
#endif
这个想法是一个主函数用一些字节多次调用byte_received,当找到一个具有有效校验和的有效数据包时,就会回调packet_received_callback。 packet_received_callback 函数未在 packet.c 中定义,但应由调用者代码提供(例如 main.c 或 Python 模块)。
如果我编译 packet.c,从中创建一个共享对象,然后使用 ctypes.cdll.LoadLibrary("./packet.so") 从 python 加载它,那么我会收到一条带有消息“未定义符号”的 OSError。这当然是意料之中的,因为我没有在任何地方提供packet_received_callback。这就是我不知道该怎么做。
我的问题是:我可以在加载共享对象时以某种方式让 ctypes 以该名称导出全局函数吗?我知道如何在 C 可执行文件中执行此操作,但不能从 Python 和 ctypes . ctypes 模块支持 C 调用 Python(通过将函数指针作为参数传递给 C 函数),这表明我想要的至少在理论上是可能的。
我已经知道我可以通过更改 C 代码来解决此问题,以便 byte_received 调用存储在全局变量中的函数指针而不是全局函数(这是我的备用计划)。我问这个问题是因为我想避免这种情况。
【问题讨论】:
-
使用您的备份计划。 C 链接器需要一个函数,而 Python 无法提供它。您必须在运行时传递 Python 函数(包装在 ctypes 中)。
-
@MarkTolonen:“[...] 和 Python 无法提供”你能解释一下原因吗?
-
Python 函数需要 Python 解释器来执行它们的字节码。它们不是 C 链接器可以使用的形式。
-
ctypes.CFUNCTYPE()的重点是将Python函数变成C程序可以使用的形式。
-
我的问题是:Python可以给链接器这样一个函数来解决符号依赖关系吗?
标签: python shared-libraries ctypes