COM-Python thread callbacks

Sue Giller sag at hydrosphere.com
Mon Apr 15 14:48:12 EDT 2002


Well, I have another question about using python COM objects with 
VB.

My application uses a VB front end that creates a Python com 
object.  The VB app passes to the Python object a VB callback 
object (class object with a single function that displays a message).

The python COM object is then called to do something. The Python 
COM object then creates a thread (threading.Thread) object that 
creates a file and writes some stuff to it, passing to the thread a 
python callback function.  When the thread ends, it uses the python 
callback fn in the python COM object to pass up a message about 
what it did.  The python callback function then passes that message 
back to the VB front end via the VB callback object, using the VB 
object's single function.  What is being passed around in a simple 
text string.

When the VB front end gets the message, it displays it in a status 
box.

Now for the problem.  If I run this application from within the VB 
IDE, everything works just fine.  But, when I compile the VB 
application into an exe and run it from the exe, the application 
abruptly closes without putting up the returned message, sometimes 
leaving the file in an open state.  The same abrupt ending will occur 
in the VB IDE if I put a break at the status box assignment line and 
then step thru the line.  It will display the msg and then close 
abruptly.

I am not an expert on COM or threads, so I am wondering if my 
design for the callback functions is the correct one, and if anyone 
has any ideas why this works in the IDE and not as an EXE.  I use 
the two levels of callbacks because I got GPFs from VB when I tried 
to pass the VB callback directly on to the thread.

Pseudo code (real code is long):

' in VB app
set VBCallBackObj = new clsCallBack
set PYWorkObj = CreateObject("Python.worker")
' pass the callback once to the python object
PYWorkObj.SetCallBack(VBCallBackObj) 
' now have COM object do something
PYWorkObj.DoSomething(inputArgs)
# python object creates the thread and does its thing, passing in its 
callback function
athread = theThread(inputArgs, self.CallBack)
athread.start()
# the thread gets done and calls back up to python object
PYWorkObj.CallBack(msg)
# the python call back function calls up to the VB object using known 
callback function name in the object, CallMe()
VBCallBackObj.CallMe(msg)


# python code snippets
# in the python com side, in the PYWorkObj
def SetCallBack(self, CallBackObj):
    """ called from outside with VB object """
    # callback obj is a vb object with a callback function named CallMe
    import win32com.client
    self._callBack = win32com.client.Dispatch(CallBackObj)

def CallBack(self, msg):
    """ a callback for the thread to signal when its done """
    self._callBack.CallMe(msg)

def DoSomething(inputArgs):
    inputargs = ProcessSomehow(inputArgs)
    currentThread = theThread(inputargs, self.CallBack)
    currentThread.start()

class theThread(threading.Thread):
    """ one thread for each job """        
    def __init__(self, args, CallBackFn):
        threading.Thread.__init__(self)
        self.args = args
        self._callBack = CallBackFn

    def run(self):
        import pythoncom
        pythoncom.CoInitialize()
        file, value = doJob(self.args)
        pythoncom.CoUninitialize()
        self._callBack("Job Done")





More information about the Python-list mailing list