我有一个简单的类的例子,我定义了我的回调:
api = CDLL('i:\api.dll')
class CallBacks():
def py_sessionCallback(aSessionHandle, aTag, aEvent):
print ('Connection State Callback for session ' + str(aSessionHandle) + ':- Event - ' + aEvent)
SESSIONCALLBACK = CFUNCTYPE(c_void_p, c_int,c_void_p,c_int,c_char_p)
sessionCallback = SESSIONCALLBACK(py_sessionCallback)
class CWrapper():
RegisterSessionStateCallback = api.RegisterSessionStateCallback
SW_RegisterSessionStateCallback.argtypes = [CallBacks.SESSIONCALLBACK]
class Session():
def __init__(self,user,passw,timeout=120):
self.server = c_char_p('https://test.con.com'.encode('utf-8')
self.timeout = timeout
self.dSessionCb = CallBacks.sessionCallback
def __conCB(self):
e = CWrapper.SW_RegisterSessionStateCallback(self.dSessionCb)
现在我想修改代码的方式,我把self.server
传递给我的回调,以实现这样的东西:
class Session():
.
.
.
def __conCB(self):
e = CWrapper.SW_RegisterSessionStateCallback(self.dSessionCb(**self.server**))
class CallBacks():
def py_sessionCallback(aSessionHandle, aTag, aEvent,**server**):
print (server + ': Connection State Callback for session ' + str(aSessionHandle) + ':- Event - ' + aEvent)
.
.
.
是否有办法将self.server
转移到py_sessionCallback
?非常感谢您的建议。
您可以使用py_object
作为类型并将您想要的任何内容传递给回调。在C代码中将其视为void*
。
你没有提供一个可复制的例子,所以这里有一个最小的例子:
test.c:
#ifdef _WIN32
# define API __declspec(dllexport)
#else
# define API
#endif
typedef void (*CALLBACK)(const char* event, void* context);
CALLBACK g_callback;
API void register_callback(CALLBACK cb) {
if(cb)
g_callback = cb;
}
API void do_something(const char* event, void* context) {
if(g_callback)
g_callback(event,context);
}
test.py:
from ctypes import *
CALLBACK = CFUNCTYPE(None,c_wchar_p,py_object)
@CALLBACK
def callback(event,obj):
print(event,obj)
class Server:
def __init__(self,a):
self.a = a
def __repr__(self):
return f'Server(a={self.a})'
dll = CDLL('./test')
dll.register_callback.argtypes = CALLBACK,
dll.register_callback.restype = None
dll.do_something.argtypes = c_wchar_p,py_object
dll.do_something.restype = None
dll.register_callback(callback)
s1 = Server(1)
s2 = Server(2)
dll.do_something('event1',s1)
dll.do_something('event2',s2)
输出:
event1 Server(a=1)
event2 Server(a=2)