Hallo!
Kann man mit ``ctypes`` auch auf DLLs und OCXe zugreifen, die von Visual Basic 6 erzeugt wurden?
Wenn ja, wie? Kleines Beispiel?
lg
Gerold
Mit ctypes auf Visual Basic 6 DLL/OCX zugreifen? (COM)
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Zuletzt geändert von gerold am Samstag 17. Februar 2007, 22:49, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Das sind IIRC COM-Objekte, also sollten die mit den COM-APIs manipulierbar sein.
Da gibts doch win32com, wenn ich mich nicht irre...
Da gibts doch win32com, wenn ich mich nicht irre...
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hi birkenfeld!birkenfeld hat geschrieben:Das sind IIRC COM-Objekte, also sollten die mit den COM-APIs manipulierbar sein. Da gibts doch win32com, wenn ich mich nicht irre...
Neuer Avatar für den Frühling -- nett
Ich habe in einem anderen Thread ganz "gscheid" behauptet, dass mir der Schritt, "ins Python 2.5 ctypes statt pywin32 aufzunehmen", sehr gefällt und ich mir wünsche, dass es demnächst viele, viele Python-Schnittstellen geben wird, die ctypes einsetzen.
Ich setze sehr oft ``win32com`` ein, um auf alte VB6-Programme zuzugreifen. Das wollte ich jetzt ändern und auf ``ctypes`` umstellen. Das einzige was ich bis jetzt gefunden habe: ``DllGetClassObject``
Aber auch die Erklärung im Windows Platform SDK hat mich nicht unbedingt weiter gebracht. Ich finde nicht raus, wie ich eine einfache Funktion in einer VB6-DLL aufrufen kann.
Um z.B. auf die Klasse ``Employee`` in der DLL ``sw3demp.dll`` zuzugreifen, würde ich mit win32com so vor gehen:
Code: Alles auswählen
from win32com.client import Dispatch
employee_class = Dispatch("sw3demp.Employee")
print employee_class.Employee_Count()
Wie würde so etwas mit ctypes funktionieren?
lg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Tut mir leid, hier kein Windows, und die Online-MSDN Library scheint inzwischen für Firefox gänzlich unbenutzbar gemacht worden zu sein.
Letztendlich glaube ich, dass es eben spezielle COM-API-Funktionen gibt, mit denen du Methoden und Eigenschaften von COM-Objekten aufrufen und manipulieren kannst.
Letztendlich glaube ich, dass es eben spezielle COM-API-Funktionen gibt, mit denen du Methoden und Eigenschaften von COM-Objekten aufrufen und manipulieren kannst.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
http://groups.google.de/group/comp.lang ... d8ea84ffd1
Jetzt bin ich wirklich verärgert
Was soll denn das schon wieder? Warum wird in der Windows-Version von Python nicht das, meines Erachtens, essentielle ``ctypes.com`` mitgeliefert? Jeder kleine Sch... in Windows ist ein COM-Objekt.
So wird wieder nichts aus einem allgemein brauchbaren Schnittstellensystem für Python.
Oder liege ich da total falsch mit der Annahme, dass ich ctypes.com für den Zugriff auf ActiveX-Objekte brauche?
Jetzt bin ich wirklich verärgert
Was soll denn das schon wieder? Warum wird in der Windows-Version von Python nicht das, meines Erachtens, essentielle ``ctypes.com`` mitgeliefert? Jeder kleine Sch... in Windows ist ein COM-Objekt.
So wird wieder nichts aus einem allgemein brauchbaren Schnittstellensystem für Python.
Oder liege ich da total falsch mit der Annahme, dass ich ctypes.com für den Zugriff auf ActiveX-Objekte brauche?
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Update: siehe untengerold hat geschrieben:Was soll denn das schon wieder? Warum wird in der Windows-Version von Python nicht das, meines Erachtens, essentielle ``ctypes.com`` mitgeliefert? Jeder kleine Sch... in Windows ist ein COM-Objekt.
Hast du es schon mal mit comtypes versucht? Das ist von Thomas Heller, dem ctypes-Autor und es scheint mir, als würde das das gleiche machen wollen wie ctypes.com. Ist zwar nicht mitgeliefert, aber es hat den Vorteil, dass es pures Python ist und daher problemlos mit deinen Programmen mitgeliefert werden kann. Ist damit sicherlich eine interessante Alternative zu pywin32.gerold hat geschrieben:So wird wieder nichts aus einem allgemein brauchbaren Schnittstellensystem für Python.
Oder liege ich da total falsch mit der Annahme, dass ich ctypes.com für den Zugriff auf ActiveX-Objekte brauche?
Edit:
Sieht so aus, als hätte Thomas Heller kein Interesse daran gehabt den COM-Code in ctypes zu maintainen. Das wird wohl zumindest einer der Gründe sein.Thomas Heller hat geschrieben:comtypes and venster to not contain any C code, so changes are good
that they work in Python 2.5 as well. AFAIK, venster still uses the
no longer supported ctypes.com package, it should be updated to
use comtypes instead.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hi Leonidas!Leonidas hat geschrieben:Hast du es schon mal mit comtypes versucht? Das ist von Thomas Heller, dem ctypes-Autor und es scheint mir, als würde das das gleiche machen wollen wie ctypes.com. Ist zwar nicht mitgeliefert, aber es hat den Vorteil, dass es pures Python ist und daher problemlos mit deinen Programmen mitgeliefert werden kann.
Das werde ich jetzt gleich ausprobieren. Dass es nicht für jede Version kompiliert werden muss, reißt comtypes wieder raus. Denn es ist wirklich kein Problem, ein paar Python-Dateien in das eigene Projekt mit aufzunehmen. Mir ging es ja genau darum.
Ich werde berichten...
lg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Das hier funktioniert schon mal. Wie es mit Parametern aussieht, werde ich noch austesten.
lg
Gerold
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
#from win32com.client import Dispatch
#employee_class = Dispatch("sw3demp.Employee")
#print employee_class.Employee_Count()
from comtypes.client import CreateObject
employee_class = CreateObject("sw3demp.Employee")
print employee_class.Employee_Count()
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
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:
"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:
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.
"comtypes" scheint auf Anhieb besser zu funktionieren, als ich es mit "win32com" je zusammengebracht hatte.
lg
Gerold
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
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' )),
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
lg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Hi Gerold.
Das hört sich interessant an. Werde kommende Woche auch mal austesten ob ich damit meine tools auch zum laufen kriege. Das wäre tatzächlich eine sehr gutz Alternative, da man für COM nicht mehr auf pywin angewiesen wäregerold hat geschrieben: "comtypes" scheint auf Anhieb besser zu funktionieren, als ich es mit "win32com" je zusammengebracht hatte.