【问题标题】:Can ctypes export symbols from Python to a shared object?ctypes 可以将符号从 Python 导出到共享对象吗?
【发布时间】: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_callbackpacket_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


【解决方案1】:

虽然ctypes 不支持此用例,但事实证明较新的cffi 库支持:https://cffi.readthedocs.io/en/latest/using.html#extern-python-new-style-callbacks

【讨论】:

    猜你喜欢
    • 2010-11-17
    • 2012-04-15
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多