我使用ctypes处理用C编写的库。这个C库允许我注册一个回调函数,我在Python中实现它。
根据ctypes API,这是回调函数类型:
_command_callback = CFUNCTYPE(
UNCHECKED(c_int),
POINTER(vedis_context),
c_int,
POINTER(POINTER(vedis_value)))
这是我写的一个装饰器,用于将函数标记为回调:
def wrap_callback(fn):
return _command_callback(fn)
要使用它,我可以简单地写:
@wrap_callback
def my_callback(*args):
print args
return 1 # Needed by C library to indicate OK response.
c_library_func.register_callback(my_callback)
我现在可以从C调用我的回调(my_callback
),这非常有效。
我遇到的问题是我将要执行的一些样板行为作为这些回调的一部分(例如返回成功标志等)。为了尽量减少样板,我试着写一个装饰器:
def wrap_callback(fn):
def inner(*args, **kwargs):
return fn(*args, **kwargs)
return _command_callback(inner)
请注意,这在功能上等同于前面的示例。
@wrap_callback
def my_callback(*args):
print args
return 1
但是,当我尝试使用此方法调用回调时,我收到以下异常,源自_ctypes/callbacks.c
:
Traceback (most recent call last):
File "_ctypes/callbacks.c", line 314, in 'calling callback function'
File "/home/charles/tmp/scrap/z1/src/vedis/vedis/core.py", line 28, in inner
return fn(*args, **kwargs)
SystemError: Objects/cellobject.c:24: bad argument to internal function
我不确定这里会发生什么导致第一个例子工作但第二个例子失败。任何人都可以对此有所了解吗?如果你可以帮助我找到一种装饰这些回调的方法,那么我可以减少样板代码!
答案 0 :(得分:0)
感谢eryksyn,我能够解决这个问题。修复如下:
def wrap_callback(fn):
def inner(*args, **kwargs):
return fn(*args, **kwargs)
return _command_callback(inner), inner
def my_callback(*args):
print args
return 1
ctypes_cb, my_callback = wrap_callback(my_callback)