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