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_callbackpacket_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