ctypes 可以将符号从 Python 导出到共享对象吗?
Can ctypes export symbols from Python to a shared object?
我正在尝试使用 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 加载它,那么我会收到一个带有消息 "undefined symbol" 的 OSError。这当然是预料之中的,因为我没有在任何地方提供 packet_received_callback
。这就是我不知道该怎么做的。
我的问题是:在加载共享对象时,我能否以某种方式让 ctypes 以该名称导出全局函数?我知道如何在 C 可执行文件中执行此操作,但是不是来自 Python 和 ctypes。 ctypes 模块支持 C 调用 Python(通过将函数指针作为参数传递给 C 函数),这表明我想要的至少在理论上是可能的。
我已经知道我可以通过更改 C 代码来解决这个问题,这样 byte_received
调用存储在全局变量而不是全局函数中的函数指针(这是我的备份计划)。我问这个问题是因为我想避免这种情况。
虽然 ctypes
不支持这个用例,但事实证明较新的 cffi
库支持:https://cffi.readthedocs.io/en/latest/using.html#extern-python-new-style-callbacks
我正在尝试使用 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 加载它,那么我会收到一个带有消息 "undefined symbol" 的 OSError。这当然是预料之中的,因为我没有在任何地方提供 packet_received_callback
。这就是我不知道该怎么做的。
我的问题是:在加载共享对象时,我能否以某种方式让 ctypes 以该名称导出全局函数?我知道如何在 C 可执行文件中执行此操作,但是不是来自 Python 和 ctypes。 ctypes 模块支持 C 调用 Python(通过将函数指针作为参数传递给 C 函数),这表明我想要的至少在理论上是可能的。
我已经知道我可以通过更改 C 代码来解决这个问题,这样 byte_received
调用存储在全局变量而不是全局函数中的函数指针(这是我的备份计划)。我问这个问题是因为我想避免这种情况。
虽然 ctypes
不支持这个用例,但事实证明较新的 cffi
库支持:https://cffi.readthedocs.io/en/latest/using.html#extern-python-new-style-callbacks