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