Python:从回调访问对象属性

时间:2013-12-04 14:03:19

标签: python python-3.x ctypes

我试图设计具有回调函数的类,该函数被转移到一些C库。需要在不更改回调参数的情况下授予对此类对象的访问权限。怎么做?

from ctypes import *
...
lib = CDLL('mylibname.so')
    ...
    class A(object):
        def __init__(self):
            CALLBACK = CFUNCTYPE(c_uint32, c_void_p)
            self.callback_func = CALLBACK(A.message_callback)
            self.param = None
        def message_callback(data):
            ... #here need access to self.param
            return 0
        def set_param(self, param):
            self.param = param
    ...
    a = A()
    lib.lib_func(param1, param2, a.callback_func)

修改 我已经使用包装函数更改了类中的回调方法:

from ctypes import *
...
lib = CDLL('mylibname.so')

class struct_t(Structure):
    pass
struct_t._fields_ = [('next', POINTER(value_pair_t)),
                         ('key', c_char_p),
                         ('value', c_char_p)]
...
class A(object):
    def __init__(self):
        self.param = None

    def wrapper(self):
        CALLBACK = CFUNCTYPE(c_uint32, POINTER(struct_t))
        def message_callback(data):
            ... # now I have access to self here
            return 0
        return CALLBACK(message_callback)

    def set_param(self, param):
        self.param = param
...
a = A()
lib.lib_func(param1, param2, a.wrapper())

它在python2中工作,但我仍然遇到python3:

的问题

追踪(最近一次通话):   在'调用回调函数'中的文件“_ctypes / callbacks.c”,第260行 TypeError:'LP_struct_t'对象不可调用

以下是相同问题的链接:Weird bug?

1 个答案:

答案 0 :(得分:2)

只需定义message_callback(self, data)并使用self.callback_func = A.CALLBACK(self.message_callback)即可。注意我使用了A.CALLBACK。将其设置为类属性。为每个实例定义它是浪费时间。

例如:

C:

typedef int (*callback_t)(void *data);

int test(const char *data, callback_t f) {
    f((void *)data); 
    return 0;
}

的Python:

from ctypes import *

class A(object):
    CALLBACK = CFUNCTYPE(c_uint32, c_void_p)

    def __init__(self):        
        self.callback_func = A.CALLBACK(self.message_callback)
        self.param = None

    def message_callback(self, data):
        self.param = cast(data, c_char_p).value
        return 0

演示:

>>> lib = CDLL('./lib.so')
>>> a = A()
>>> lib.test.argtypes = [c_char_p, A.CALLBACK]
>>> lib.test("updated", a.callback_func)
0
>>> a.param
'updated'