如何将其他参数传递给我的回调?

How to pass additional arguments to my callback?

我有以下 class 定义回调的简单示例:

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)