win32com 'pass by reference' problem

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
irimi
User
Beiträge: 4
Registriert: Samstag 16. Februar 2008, 22:11

Hallo,

nachdem ich nach diversen Recherchen per Suchmaschine nicht weiterkomme, will ich es mal hier versuchen :D

Wie ich verstanden habe: wenn ich nun eine Funktion meines COM Servers aufrufen will, die eine "pass by reference" value hat, gibt die win32com Implementierung von Python ein Tupel zurück:

Code: Alles auswählen

long GeValue(LPCTSTR device, short Value)
wird

Code: Alles auswählen

ret, value = GetValue("mein device") 
o.ä. !?

Nun bekomme ich aber bei der Funktion, die ich bei "meinem" COM Server absprechen will, aber immer folgende Fehlermeldung

Code: Alles auswählen

self.__server = win32com.client.Dispatch(self.__AUTO_APPL)

def getValue(self,identifier,offset,size):
      retVal=None
      if self.__server:
          result, answer=self.__server.GetValueBySymbol(identifier,offset,size)
            retValue=answer
      return retVal

  result, answer=self.__server.GetValueBySymbol(symbol,offset,size)
  File "<COMObject Auto.Application>", line 2, in GetValueBySymbol
pywintypes.com_error: (-2147352561, 'Parameter nicht optional.', None,
None)

Bediene ich diesen Parameter, gibt es eine andere Fehlermeldung

Code: Alles auswählen

   def getValue(self,identifier,offset,size):
        retVal=None
        answer = [] # =None als Alternative gleich
        if self.__server:
            result, answer=self
.__server.GetValueBySymbol(identifier,offset,size,answer)
            retValue=answer
        return retVal

 result, answer=self.__server.GetValueBySymbol(symbol,offset,size,answer)
  File "<COMObject Auto.Application>", line 2, in GetValueBySymbol
pywintypes.com_error: (-2147352571, 'Typkonflikt.', None, 4)
Die IDL des COM Servers, den ich ansprechen will sieht so aus:

Code: Alles auswählen

[id(2), helpstring("method GetValueBySymbol")] long GetValueBySymbol(BSTR szSymbol, short shOffset, short shLength, [out,retval] VARIANT* pValue);
makepy sagt mir folgendes:

Code: Alles auswählen

# Created by makepy.py version 0.4.95

      def GetValueBySymbol(self, szSymbol=defaultNamedNotOptArg,shOffset=defaultNamedNotOptArg, shLength=defaultNamedNotOptArg,pValue=pythoncom.Missing):
            """method GetValueBySymbol"""
            return self._ApplyTypes_(2, 1, (3, 0), ((8, 0), (2, 0), (2, 0),(16396, 10)), 'GetValueBySymbol', None,szSymbol, shOffset, shLength,pValue)
Und in Perl funktioniert es ohne Probleme mit

Code: Alles auswählen

sub AUTO_bGetValue {
      my $self     = shift;
      my $symbol   = shift;
      my $offset   = shift || 0;
      my $length   = shift || 1;
      my $dataref  = shift || undef;
      my $response = Variant(VT_BYREF|VT_VARIANT, Variant(VT_BSTR, ""));
      my $rc       = 0;

      &LIB_vLog("GetValue $symbol offset $offset length $length");
      if ($self->{objApp}->GetValueBySymbol($symbol, $offset, $length,$response) == 0) {
            $rc = 1;
            &LIB_vLog("GotValue $response");
            $$dataref = $response if (defined $dataref);
      }
      else {
            &LIB_vLog("Failed (error while getting value!)");
      }
      return $rc;
}
Muss ich einen bestimmten Win32Type benutzen oder wie ?? Den COM Server kann ich leider nicht ändern, da er nicht von mir ist.

irimi
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Auch, wenn es Problem nicht löst:

Der Perl-Code ist hässlich!
Und der Python-Code auch...
Tu dir mal Perl Best Practices und PEP 8 an!

Und warum taucht da eine deutsche Fehlermeldung auf? Oo
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

audax hat geschrieben:Und warum taucht da eine deutsche Fehlermeldung auf? Oo
Weil die COM-Fehlermeldungen in der Sprache sind, auf die die Applikation eingestellt ist. Das machen sogar Komponenten, die in Windows schon mitgeliefert sind. :evil:
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
irimi
User
Beiträge: 4
Registriert: Samstag 16. Februar 2008, 22:11

audax hat geschrieben: Der Perl-Code ist hässlich!
Und der Python-Code auch...
Tu dir mal Perl Best Practices an!
Sorry, da "tu" ich mir eher ein Python Buch an, da ich von Perl keine Ahnung habe und das auch so belassen will (& btw der Code auch nicht von mir stammt).

Der Python Code ist auf das eigentliche Problem reduziert und bei copy/paste hat halt die Formatierung gelitten ...
aber das ist ja wohl kein Problem oder :wink:

Aber hat denn keiner einen kleinen Tipp wie der Funktionsaufruf korrekt in Python funktioniert ?

irimi
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Möglicherweise liegt die Antwort in diesem Thread versteckt? (Erster Treffer auf "google: win32com parameter not optional")
irimi
User
Beiträge: 4
Registriert: Samstag 16. Februar 2008, 22:11

mkallas hat geschrieben:Möglicherweise liegt die Antwort in diesem Thread versteckt? (Erster Treffer auf "google: win32com parameter not optional")
Herzlichen Dank !!! Man muss also nur die richtigen Suchbbegriffe eingeben :roll:

Habe es zwar noch nicht zum Laufen gebracht, aber dieser Thread bringt mich jednfalls schon mal weiter !! :D
irimi
User
Beiträge: 4
Registriert: Samstag 16. Februar 2008, 22:11

irimi hat geschrieben:
mkallas hat geschrieben:Möglicherweise liegt die Antwort in diesem Thread versteckt? (Erster Treffer auf "google: win32com parameter not optional")
Herzlichen Dank !!! Man muss also nur die richtigen Suchbbegriffe eingeben :roll:

Habe es zwar noch nicht zum Laufen gebracht, aber dieser Thread bringt mich jednfalls schon mal weiter !! :D
Bingo ! Problem mit Hilfe des o.g. Tipps gelöst, man muss win32com.client.gencache verwenden:

Code: Alles auswählen

class MyClass(object):

    CLSID = pywintypes.IID('{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}')
    MajorVersion = 1
    MinorVersion = 0
    LCID = 0x0

    APPLICATION = "MyApplication.Application"
    
    def __init__(self):
        self.__early=win32com.client.gencache.EnsureModule(self.CLSID, self.LCID, self.MajorVersion, self.MinorVersion)
        self.__appl = win32com.client.Dispatch(self.APPLICATION)
        self.__appl = self.__early.MyApplication(self.__appl)
        #print repr(self.__appl)

    def getValue(self, identifier, offset, size):
        result, answer=self.__appl.GetValueBySymbol(identifier, offset, size)
        return answer

Danke,
irimi
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Wozu brauchst du doppelte Unterstriche? Diese markieren nichts als "privat", sie sind nur dazu da um Namenskonflikte zu verhindern.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten