【问题标题】:Callbacks with ctypes (How to call a python function from C)使用 ctypes 的回调(如何从 C 调用 python 函数)
【发布时间】:2016-02-02 17:57:02
【问题描述】:

是否可以从 C dll 函数调用 Python 函数?

我们考虑这个 C 函数:

 void foo( void (*functionPtr)(int,int) , int a, int b);

在 Python 上,我想调用 foo 并将回调设置为 Python 函数:

def callback(a, b):
    print("foo has finished its job (%d, %d)" % (a.value,b.value))

dll.foo( callback, c_int(a), c_int(b) )

不幸的是,ctypes 文档对这个主题的理解很浅,上面的代码不起作用。

【问题讨论】:

  • Ctypes 回调文档:docs.python.org/3.3/library/…
  • 不幸的是,该教程通常是 ctypes 的事实上的参考。 Mark 为您提供了教程链接,但肯定在 reference section 2.4 中记录了足够多的文档以超出您的尝试范围:“由这些工厂函数创建的函数原型可以以不同的方式实例化,具体取决于参数的类型和数量call ...原型(可调用),从Python可调用“创建一个C可调用函数(回调函数)”。

标签: python ctypes


【解决方案1】:
import ctypes as c

@c.CFUNCTYPE(None, c.c_int, c.c_int)
def callback(a, b):
    print("foo has finished its job (%d, %d)" % (a.value, b.value))

dll.foo(callback, a, b) # assuming a,b are ints

如果您需要 stdcall 调用约定,use WINFUNCTYPE instead

注意:如果foo 可能会存储回调以在以后调用,那么请确保 Python 回调是活动的(如果使用装饰器在全局级别定义它就足够了,如示例中所示 -模块在 Python 中基本上是不朽的,除非您尝试显式删除它们)。

【讨论】:

    【解决方案2】:

    使用CFUNCTYPE创建回调类型:

    c_callback = CFUNCTYPE(None, c_int, c_int)(callback)
    dll.foo(c_callback, a, b)
    

    【讨论】:

    • OP 是明确的,所以我也是。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2021-05-01
    • 2016-11-11
    相关资源
    最近更新 更多