Passing self though to callbacks

Glenn Pierce <[email protected]> Thu, 3 Mar 2016 08:32:27 +0000
Newsgroups gmane.comp.python.ctypes
Message-ID <CAM5ipV_NJ==Q_u3whMH6T=RdaW45Uu_cSq-38z7Jzo4_e5uKgA@mail.gmail.com>
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