Auslesen von COM-Event-Parameter schlägt fehl (object is not callable)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Headbucket
User
Beiträge: 1
Registriert: Donnerstag 20. Juli 2017, 08:05

Donnerstag 20. Juli 2017, 08:38

Hallo zusammen,

mein erster Beitrag im Forum und direkt ein neues Thema :oops:
Nachdem ich nun aber 1,5 Tage nach einer Lösung suche, hoffe ich hier Hilfe zu erhalten. Ich muss erwähnen, dass ich ein absoluter Python-Neuling bin.

Hintergrund:
Ich möchte auf ein Event aus einer COM-Schnittstelle reagieren und den in diesem Event übergebenen Parameter auswerten.
Das Event ist folgendermaßen definiert:

Code: Alles auswählen

HRESULT OnTransiente([in] ITransientenList* TransientenList);
Als Python-Bibliothek habe ich sowohl pywin32 und comtypes verwendet. Mit beiden beiden Bibliotheken wird das Event richtig ausgelöst. Allerdings bekomme ich bei beiden Bibliotheken beim Auslesen des Objektes folgenden Fehler

pywin32: TypeError: 'PyIDispatch' object is not callable
comtypes: 'POINTER(ITransientenList)' object is not callable

Bei pywin32 konnte ich das Problem folgendermaßen lösen:

Code: Alles auswählen

import win32com.client
import pythoncom
[...]

class EventHandler:
    def OnTransiente(self, TransientenList):
		# Arbeiten mit TransientenList sorgt für Fehler
        list = win32com.client.Dispatch(TransientenList)        
		# Arbeiten mit list funktioniert        

        return True

def Main():    
    #my_app = win32com.client.Dispatch("MyApp.CSApplication") #dynamic
    my_app = win32com.client.gencache.EnsureDispatch("MyApp.CSApplication") #static
    
    handler = win32com.client.WithEvents(my_app, EventHandler)
    

    while True:
        try:
            pythoncom.PumpWaitingMessages()
            time.sleep(0.01)
        except KeyboardInterrupt:
            break
    
    del cs_app    

Main()
Bei comtypes klappt ein analoges vorgehen leider nicht:

Code: Alles auswählen

import comtypes.client
import pythoncom
[...]

class EventSink(object):
    def OnTransiente(self, TransientenList):
		# Arbeiten mit TransientenList sorgt für Fehler
        list = comtypes.client.CreateObject(TransientenList) # Fehler		     

        return True

def Main():    
	my_app = comtypes.client.CreateObject("MyApp.CSApplication")
    
    sink = EventSink()
	handler = comtypes.client.GetEvents(my_app, sink)    

    while True:
        try:
            pythoncom.PumpWaitingMessages()
            time.sleep(0.01)
        except KeyboardInterrupt:
            break
    
    del cs_app    

Main()
Hier erhalte ich:
TypeError: Cannot construct guid from <POINTER(ITransientenList) ptr=0x2deee64 at 3f9f940>

Hat jemand eine Idee, was ich falsch mache?

Der Hintergrund, weshalb ich gerne comtypes anstatt pywin32 verwenden würde ist der, dass ich auf ein SAFEARRAY zugreifen möchte, welches wohl mit comtypes etwas leichter sein soll.

Vielen Dank fürs lesen!

Grüße
Headbucket

Edit: Vielen Dank für's Editieren der python-codebox.
Der Übergabeparameter ist übigens folgendermaßen definiert:

Code: Alles auswählen

interface ITransientenList : IDispatch {
    [id(0x000000c9)]
    HRESULT Add([out, retval] ITransiente_** Result);
    [id(0x000000ca), propget]
    HRESULT Count([out, retval] long* Value);
    [id(0x000000cb), propget]
    HRESULT Items([in] long Index, [out, retval] ITransiente_** Value);
    [id(00000000), propget]
    HRESULT _Default([in] long Index, [out, retval] ITransiente_** Value);
};
Bei comtypes kann ich Count ohne Probleme auslesen. Bei Items jedoch scheitere ich. Wahrscheinlich, weil diese in einem erneuten Interface definiert sind :-/
Zuletzt geändert von Anonymous am Donnerstag 20. Juli 2017, 08:47, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Antworten