2010-07-14 31 views
4

Je suis en train de créer un objet COM à partir d'une dll dans un nouveau thread en Python - donc je peux faire fonctionner une pompe de message dans ce fil:Pourquoi ne puis-je pas créer un objet COM dans un nouveau thread en Python?

from comtypes.client import CreateObject 
import threading 

class MessageThread(threading.Thread): 

    def __init__(self): 
     threading.Thread.__init__(self) 
     self.daemon = True 

    def run(self): 
     print "Thread starting" 
     connection = CreateObject("IDMessaging.IDMMFileConnection") 
     print "connection created" 

a = CreateObject("IDMessaging.IDMMFileConnection") 
print "aConnection created" 
t = MessageThread() 
t.start() 

c'est la trace d'erreur que je reçois:

aConnection created 
Thread starting 
>>> Exception in thread Thread-1: 
Traceback (most recent call last): 
    File "c:\python26\lib\threading.py", line 532, in __bootstrap_inner 
    self.run() 
    File "fred.py", line 99, in run 
    self.connection = CreateObject("IDMessaging.IDMMFileConnection") 
    File "c:\python26\lib\site-packages\comtypes\client\__init__.py", line 235, in CreateObject 
    obj = comtypes.CoCreateInstance(clsid, clsctx=clsctx, interface=interface) 
    File "c:\python26\lib\site-packages\comtypes\__init__.py", line 1145, in CoCreateInstance 
    _ole32.CoCreateInstance(byref(clsid), punkouter, clsctx, byref(iid), byref(p)) 
    File "_ctypes/callproc.c", line 925, in GetResult 
WindowsError: [Error -2147221008] CoInitialize has not been called 

Des idées?

Répondre

7

Vous devez avoir appelé CoInitialize() (ou CoInitializeEx()) sur un thread avant de pouvoir créer des objets COM sur ce thread.

from win32com.client.pythoncom import CoInitialize 
CoInitialize() 
2

Pour autant que je me souviens (il y a longtemps I'e programmé beaucoup de temps avec les composants COM) vous devez appeler CoInitialize sur chaque fil si votre objet COM utilise STA.

http://msdn.microsoft.com/en-us/library/ms678543(VS.85).aspx

Mais Je ne sais pas comment appeler cette fonction en python.

Voici le MSDN Doc

http://msdn.microsoft.com/en-us/library/ms678543(VS.85).aspx

+0

Vous avez besoin de CoInitializeEx() indépendamment de ce que l'objet utilise. – sharptooth

+0

beaucoup de thx à vous deux ... Je viens de le faire et maintenant je ole32.dll ne semble pas revenir de CoCreateInstance. J'essaye de créer l'objet avant que je commence la pompe de message - est-ce correct? – DangerMouse

+0

Got it ... d'oh ... ma DLL COM est implémentée dans VB6 et je l'ai définie sur STA plutôt que sur apartment threaded ... tout fonctionne maintenant ... a des objets COM sur un thread séparé envoyant des messages à Excel ;) – DangerMouse

1

Juste pour mettre à jour avec l'expérience actuelle à l'aide PyCharm et Python 2.7: Vous devez importer:

from pythoncom import CoInitializeEx 
from pythoncom import CoUninitialize 

puis pour courir le fil:

def run(self): 
    res = CoInitializeEx(0) 
    #<your code> 
    CoUninitialize() 

PyCharm obtenir con fusionné avec l'appartement STA, vous devez activer le multithreading vrai.

Il est important que chaque CoInitialize() se termine par un CoUninitialize(), alors assurez-vous que votre code respecte également cette règle en cas d'erreur.