Re: Passing self though to callbacks
Glenn Pierce <[email protected]> Thu, 3 Mar 2016 10:38:06 +0000
| Newsgroups | gmane.comp.python.ctypes |
|---|---|
| Message-ID | <CAM5ipV92ZmzxDP7t8uGgjsB98_a65qVTrK-F9uM5fW+oo4oe0Q@mail.gmail.com> |
Update. I can pass the int now. I was retrieving with.value and not .contents If anyone has a simpler way though please let me know. On 3 March 2016 at 08:32, Glenn Pierce <[email protected]> wrote: > Hi I am having trouble getting self passed through to callbacks. > I know ctypes usually takes care of this but in my case it does not > because the c API I am wrapping requires the function pointers to be > placed into a structure > which then is passed to the function that sets up the connection. I > believe this stops the ctypes self propagation from working. > Is there a way to get it working in this case ? > > > An example is below. > > The functions I have wrap except a context which is just callback > data. So I have tried passing id through this > like > > self.handle = self._Create(C.byref(self.callback_structure), > C.c_void_p(id(self))) > > in the callback I cast back like > > self = C.cast(context, C.py_object).value > > > This does not seem to work well though. With one object it is find but > when adding different callback objects of the same style the cast back > sometimes returns the wrong object. > Not sure why though. Neither object gets garbage collected so id > should be valid unique. > > I would try to pass a unique int / dict mapping though context but how > can I pass an int through a void* ? > > If anyone has any suggestions that would be great. Thanks > > > > if sys.platform == 'win32': > CallbackType = C.WINFUNCTYPE > else: > CallbackType = C.CFUNCTYPE > > SessionListenerSessionLostFuncType = CallbackType(None, C.c_void_p, > C.c_int, C.c_int) # context sessionId reason > > class SessionListenerCallBacks(C.Structure): > _fields_ = [ > ("SessionLost", SessionListenerSessionLostFuncType) > ] > > > class SessionListener(object): > > > def __init__(self, callback_data=None): > > super(SessionListener, self).__init__() > > self.callback_structure = SessionListenerCallBacks() > self.callback_data = callback_data > > self.callback_structure.SessionLost = > SessionListenerSessionLostFuncType(SessionListener._OnSessionLostCallBack) > self.callback_structure.SessionMemberAdded = > SessionListenerSessionMemberAddedFuncType(SessionListener._OnSessionMemberAddedCallback) > > # I have remove the wrapper for this for simplicaity > # The prototype is # _create(const sessionlistener_callbacks* > callbacks, const void* context); > self.handle = self._Create(C.byref(self.callback_structure), > C.c_void_p(id(self))) > > > def __del__(self): > if self.handle: > return self._Destroy(self.handle) > > @staticmethod > def _OnSessionLostCallBack(context, sessionId, reason): > self = C.cast(context, C.py_object).value > self.OnSessionLostCallBack(self.callback_data, sessionId, reason) > > def OnSessionLostCallBack(self, context, sessionId, reason): > pass ------------------------------------------------------------------------------ Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140