系统错误:Objects/cellobject.c:24:内置函数参数错误

0 投票
1 回答
4310 浏览
提问于 2025-04-18 10:06

我正在使用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

我不太明白为什么第一个例子可以工作,而第二个例子却失败了。有没有人能帮我解释一下?如果你能帮我找到一种方法来装饰这些回调,以减少重复代码,那就更好了!

1 个回答

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)

撰写回答