我试图设计具有回调函数的类,该函数被转移到一些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?
答案 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'