From: Bronner, G. <gre...@le...> - 2007-12-14 23:28:36
|
It can be done, and I've done it multiple times, but it isn't exactly the easiest thing to do. I haven't seen a good discussion of this anywhere: My typical approach is to write a C++ class that implements the listener interface(es). My C++ object has a captive python object delegate, and the C++ callbacks simply use the python C-API to determine if the the delegate object has a function of a specific name, and if it exists, the callback calls the python function. A further wrinkle is that event callbacks can be done on threads other than the main python interpreter thread. In that case, every C++ callback that modifies python variables has to lock the global interpreter lock using PyGILState_STATE gstate; gstate =3D PyGILState_Ensure(); =09.... PyGILState_Release(gstate); Likewise, the functions that start processing the event loop (or need to block while other events are processed) have to release the global interpreter lock using Py_BEGIN_ALLOW_THREADS =2E.. Py_END_ALLOW_THREADS I use it through a swig exception declaration: %define THREAD_WRAP(x) %exception x=20 =7B /* Generated by THREAD_WRAP x */ Py_BEGIN_ALLOW_THREADS =24action Py_END_ALLOW_THREADS =7D %enddef example: THREAD_WRAP(A::b); As a side effect of this, I never have to wrap the actual callback functions -- I just wrap the constructor for the C++ class that implements the callback functions, and the function that accepts a python object delegate, as well as the the functiont that starts the event loop. So I might have a script that does this: import msgCallback class MyCallback(object): =09def onMsg(arg1, arg2): =09=09print =22OnMsg called=21=22 cobj=3DmsgCallback.PythonCCallbackWrapper() cobj.setDelegate(MyCallback()) msgCallback.startEventLoop() To do this correctly requires a very good working knowledge of the target API, SWIG, and the Python C-API, but when done properly, it gives you the flexibility of writing extremely flexible event-driven programs. ------------------------------ Message: 5 Date: Wed, 12 Dec 2007 15:54:08 -0800 (PST) From: mattdavis <someoneinjapan=40gmail.com> Subject: =5BSwig-user=5D new to swig and callbacks wondering if swig can =09do this and any pointers. To: swig-user=40lists.sourceforge.net Message-ID: <14306927.post=40talk.nabble.com> Content-Type: text/plain; charset=3Dus-ascii Hi everyone, I am new to swig and have some questions about callbacks. I would love any help, hints, or links to pages that might contain more information for me.=20 So here is my current situation. I have 5 function that I am trying to wrap in swig. There are 2 RegisterForNotification function which accept an EventID and an either an EventResponder or an EventListner. The EventListener and EventResponder are functions which get called when an event is raised RaiseEvent notifies all the listeners first and then calls the event responder. There may be multiple listeners, but only one responder. The listeners may do some processing, but do not provide a result. The responder handles the event and returns a result. the other 2 are UnregisterForNotification which takes an EventID and either an EventListener or EventResponder. The other question I have is do I need to wrap the EventListner and EventResponder? The following code is in the .h file typedef CBFunctor3wRet<EventId, const String&, const Argument&, Result> EventListener; typedef CBFunctor3wRet<EventId, const String&, Argument&, Result> EventResponder; does that mean that it will be wrapped or do I have to specifically include it? I have also already wrapped my String and Result classes but haven't yet wrapped the Argument class. I am assuming that I will need to wrap the Argument class as well. What I want to be able to do is call these functions from a python script.=20 So for example if a REQUIREPASSWORD event pops up then I can send it a password from the script and I get a result back. I have done a little digging around and from what I can understand to do call backs I have to have the callback functions defined in C and I wrap them with swig. Please correct me if I am wrong. For what I am trying to do that doesn't fit very well. I want to be able to write function in python and be able to pass them in. Is this possible? I have also seen some posts and links to TypeMaps. This was a little deeper into swig then I thought I would have to go. I am not opposed to doing this, I was just hoping to know if that is the right approach to this problem or if there is a more simple approach to this. Any help is greatly appreciated. --=20 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - = - - - - - - - This message is intended only for the personal and confidential use of the = designated recipient(s) named above. If you are not the intended = recipient of this message you are hereby notified that any review, = dissemination, distribution or copying of this message is strictly = prohibited. This communication is for information purposes only and = should not be regarded as an offer to sell or as a solicitation of an = offer to buy any financial product, an official confirmation of any = transaction, or as an official statement of Lehman Brothers. Email = transmission cannot be guaranteed to be secure or error-free. Therefore, = we do not represent that this information is complete or accurate and it = should not be relied upon as such. All information is subject to change = without notice. -------- IRS Circular 230 Disclosure: Please be advised that any discussion of U.S. tax matters contained within = this communication (including any attachments) is not intended or written = to be used and cannot be used for the purpose of (i) avoiding U.S. tax = related penalties or (ii) promoting, marketing or recommending to another = party any transaction or matter addressed herein. |