I am trying to design class with callback function which is transferred to some C library. Need to grant access to object of this class without changing callback arguments. How to do this?
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)
EDIT: I've changed callback method in the class with wrapper function:
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())
It works in python2, but I still have issues with python3:
Traceback (most recent call last): File "_ctypes/callbacks.c", line 260, in 'calling callback function' TypeError: 'LP_struct_t' object is not callable
Here is link with same issue: Weird bug?
self? Just use a method as the callable, as I showed you.lib_funcreturns. Then it will be garbage collected, deallocating the thunk code and data. If the thunk code still exists to callclosure_fcn, then who knows what garbagep->callablepoints to. Apparently in this case it's theLP_struct_t.