Und hier ein Beispiel mit Rückgabeparametern, die im Visual Basic 6 als ``byref`` angegeben sind.
Das hier ist der Kopf der Funktion, wie sie im Visual Basic definiert wurde:
Code: Alles auswählen
'***************************************************************************************************
'* Erstellt von: Gerold Penz Am: 17.10.2000 17:35:03
'* Beschreibung: Gibt die neue Bonnummer und die Zufallsnummer zurück
'* 000 00000 0000000
'* 000 00000 AAAAA
'* Rückgabe: eTrue = OK
'* eErrorMisc = Fehler
'***************************************************************************************************
Public Function GetNewBonnummer( _
ByVal iKassaNr As Integer, _
ByVal dBonzeit As Date, _
ByRef sBack_NewBonnummer As String, _
ByRef lBack_Monatsschluessel As Long, _
ByRef lBack_NeuerZaehler As Long, _
ByRef sBack_NewBonnummerZufall As String _
) As Enum_TrueFalseError
"comtypes" legte beim ersten Aufruf von "CreateObject" im Ordner "J:\Python24\Lib\site-packages\comtypes\gen" die Datei "sw3dpos.py" an. In dieser wird auf die Datei "_5E257BE7_C564_4128_9A0B_A6DB037DA844_0_8_1.py" verwiesen. Wenn man diese Datei öffnet, dann findet man in dieser eine komplette Typdefinition der aufgerufenen DLL.
Ich suche mal die interessantesten Stellen zur aufgerufenen Funktion raus:
Code: Alles auswählen
class _Bon_Real(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IDispatch):
_case_insensitive_ = True
_iid_ = GUID('{340EC989-AEC8-4A0F-BDC8-92618BE0B3C7}')
_idlflags_ = ['nonextensible', 'dual', 'oleautomation', 'hidden']
_Bon_Real._methods_ = [
Code: Alles auswählen
COMMETHOD([dispid(1610809347)], HRESULT, 'GetNewBonnummer',
( ['in'], c_short, 'iKassaNr' ),
( ['in'], c_double, 'dBonzeit' ),
( ['in', 'out'], POINTER(BSTR), 'sBack_NewBonnummer' ),
( ['in', 'out'], POINTER(c_int), 'lBack_Monatsschluessel' ),
( ['in', 'out'], POINTER(c_int), 'lBack_NeuerZaehler' ),
( ['in', 'out'], POINTER(BSTR), 'sBack_NewBonnummerZufall' ),
( ['retval', 'out'], POINTER(comtypes.gen._2A06DCF9_CD17_4277_AB15_DEDD1EF2F6E2_0_329_0.Enum_TrueFalseError), 'None' )),
Mit diesen Informationen ist es ein Leichtes, die Parameter korrekt vorzubereiten. Sogar ein Hinweis auf das Rückgabe-Enum (Enum_TrueFalseError) ist zu finden. Die Definition ist also in der Datei "_2A06DCF9_CD17_4277_AB15_DEDD1EF2F6E2_0_329_0.py". -- wenn man sie braucht.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
import datetime
from comtypes.client import CreateObject
import comtypes as ct
bon_real = CreateObject("sw3dpos.Bon_Real")
def to_win_serialdate(datetimeobj):
"""
Wandelt das `datetimeobj` in das "Serielle Datumsformat" von
Windows um. Dieses beginnt beim 1.1.1900 und zählt jeden Tag
vor dem Komma. Nach dem Komma steht die Zeit. 0,5 bedeutet
12:00 Uhr Mittag
"""
begindatetime = datetime.datetime(1900, 1, 1)
td = datetimeobj - begindatetime + datetime.timedelta(days = 2)
return td.days + (1.0 / (24 * 60 * 60) * td.seconds)
iKassaNr = ct.c_short(1)
dBonzeit = ct.c_double(to_win_serialdate(datetime.datetime.now()))
sBack_NewBonnummer = ct.BSTR()
lBack_Monatsschluessel = ct.c_int()
lBack_NeuerZaehler = ct.c_int()
sBack_NewBonnummerZufall = ct.BSTR()
print bon_real.GetNewBonnummer(
iKassaNr,
dBonzeit,
sBack_NewBonnummer,
lBack_Monatsschluessel,
lBack_NeuerZaehler,
sBack_NewBonnummerZufall
)
print "iKassaNr:", iKassaNr.value
print "dBonzeit:", dBonzeit.value
print "sBack_NewBonnummer:", sBack_NewBonnummer.value
print "lBack_Monatsschluessel:", lBack_Monatsschluessel.value
print "lBack_NeuerZaehler:", lBack_NeuerZaehler.value
print "sBack_NewBonnummerZufall:", sBack_NewBonnummerZufall.value
Code: Alles auswählen
(BSTR(u'001391140000039'), c_long(39114), c_long(39), BSTR(u'00139114PMHRM'), -1)
iKassaNr: 1
dBonzeit: 39130.9320139
sBack_NewBonnummer: 001391140000039
lBack_Monatsschluessel: 39114
lBack_NeuerZaehler: 39
sBack_NewBonnummerZufall: 00139114PMHRM
"comtypes" scheint auf Anhieb besser zu funktionieren, als ich es mit "win32com" je zusammengebracht hatte.
lg
Gerold
