Seite 1 von 1
Typ HANDLE in Python übersetzen
Verfasst: Donnerstag 5. Juli 2007, 12:03
von HarryPython
Hi
Ich bin gerade dabei ein Programmteil von C++ in Python zu übersetzen. Jetzt finde ich der Header Datei eine Variable vom Typ HANDLE. Wie kann ich in Python so ein Typ definieren. Die dll die ich benutze möchte solch einen Typ haben.
Gruß Harry P
Verfasst: Donnerstag 5. Juli 2007, 13:08
von BlackJack
Da wirst Du herausfinden müssen, was für ein Typ `HANDLE` ist. Irgendwo muss das ja definiert sein.
Verfasst: Freitag 6. Juli 2007, 07:41
von HarryPython
Hi Black,
genau das ist das Problem. Ich hab schon mein Rechner nach der windows.h durchsucht und nichts gefunden. Hab auch schon fleißig gegoogelt um herauszufinden was das wohl für ein Typ ist. Bin aber leider nicht fündig gewurden.
Verfasst: Freitag 6. Juli 2007, 07:52
von Zap
Ich bin in der Visual-Studio-Lib auf das hier gestoßen
Verfasst: Freitag 6. Juli 2007, 12:09
von HarryPython
Ja. Aber das kann ja nicht alles sein...
HANDLE stellt doch eine Verbindung zu einem Treiber her. oder so in etwa. Auf jeden Fall bekommt das C++ Programm so eine Info ob ein Signal an meiner PCMCIA Karte angekommen ist.
Verfasst: Freitag 6. Juli 2007, 12:11
von birkenfeld
Wieso? Meist ist das Handle ein Pointer zu einer OS-internen Struktur. Und solch ein Pointer kann problemlos zu einem Integer gecastet werden.
Verfasst: Freitag 6. Juli 2007, 19:34
von Joghurt
HarryPython hat geschrieben:Ja. Aber das kann ja nicht alles sein...
HANDLE stellt doch eine Verbindung zu einem Treiber her. oder so in etwa.
So in etwa... Das läuft analog zum Datei öffnen auf Betriebssystemebene:
Wenn du das System bittest, doch mal bitte die Datei "foo" zu öffnen, gibt es dir ein Handle zurück. Dieses Handle ist einfach nur eine Nummer.
Du willst ja nicht immer sagen müssen, "also, die Datei, die ich eben, so gegen halb 4 geöffnet habe, nein, nicht die um 15:32, die andere, also bei der möchte ich gerne folgendes dazuschreiben". Stattdessen sagt man "Hier, die Datei mit dem Handle 5, mit der ..." Das BS weiss dann ganz genau, welche Datei gemeint ist.
Analog ist es mit dem Treiberhandle. Das wird auch einmal geöffnet und dann kannst du über das Handle dich darauf beziehen.
PS: Wenn du mal "low-level" Dateimanipulation unter Python machen willst, kannst du das mit dem os-Modul tun:
Code: Alles auswählen
>>> import os
>>> handle = os.open("/tmp/foo", os.O_CREAT | os.O_RDWR) # ggf. ein anderes Verzeichnis, wenn du unter Windows bist
>>> print handle
3 # kann auch eine andere Zahl sein
>>> os.write(handle, "Hallo")
5 # Anzahl geschriebener Bytes
>>> os.write(3, " Welt") # Alternativ, statt 3 hier den Wert von handle einsetzen
5
>>> os.close(handle)
Die Datei /tmp/foo enthält jetzt "Hallo Welt"
Verfasst: Sonntag 8. Juli 2007, 12:08
von Trundle
birkenfeld hat geschrieben:Wieso? Meist ist das Handle ein Pointer zu einer OS-internen Struktur. Und solch ein Pointer kann problemlos zu einem Integer gecastet werden.
Oder auch nicht.
Code: Alles auswählen
In [18]: import ctypes
In [19]: import platform
In [20]: ctypes.sizeof(ctypes.c_void_p) == ctypes.sizeof(ctypes.c_int)
Out[20]: False
In [21]: platform.machine()
Out[21]: 'x86_64'
Verfasst: Sonntag 8. Juli 2007, 12:25
von birkenfeld
Integer != int.
Verfasst: Mittwoch 11. Juli 2007, 15:30
von HarryPython
Ok. Soweit so gut.
Habs jetzt etwas besser verstanden aber die Lösung bekomme ich damit leider immer noch nicht hin. Daher hier der Quelltext:
So sieht das ganze in C++ aus:
Code: Alles auswählen
HANDLE rxEventHandle #befindet sich in der h. Datei
rxEventHandle = CreateEvent(Null, False, False, Null)
vErr = ncdSetNotification(port, (unsigned long*)&rxEventHandle, 1)
Meine nicht funktionierende Lösungsansätze:
Code: Alles auswählen
test = pointer(c_ulong())
rxEventHandle = win32event.CreateEvent(None, False, False, None)
test = rxEventHandle
print rxEventHandle
vErr = candll.ncdSetNotification(port, byref(test), 1)
mit der Fehlermeldung:
<PyHANDLE at 10738176 (5996)>
Traceback (most recent call last):
File "D:\Henry\RPU_repository_copy\eclipse_workspace_henry\SSP-Control\src\Canoe_Control.py", line 147, in <module>
vErr = candll.ncdSetNotification(port, byref(test), 1)
TypeError: byref() argument must be a ctypes instance, not 'PyHANDLE'
ODER:
Code: Alles auswählen
rxEventHandle = win32event.CreateEvent(None, False, False, None)
print rxEventHandle
vErr = candll.ncdSetNotification(port, (rxEventHandle), 1)
mit der Fehlermeldung:
[quote]
<PyHANDLE at 10738152 (5996)>
Traceback (most recent call last):
File "D:\Henry\RPU_repository_copy\eclipse_workspace_henry\SSP-Control\src\Canoe_Control.py", line 147, in <module>
vErr = candll.ncdSetNotification(port, (rxEventHandle), 1)
ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: Don't know how to convert parameter 2[/quote][/list]
Wie man sieht ist die Übersetzung von [size=150](unsigned long*)&rxEventHandle[/size] mein Problem. Wenn dafür jemand eine Lösung hat wäre das natürlich ein Traum. Kommentare zu meinen Fehlermeldungen würden natürlich auch schon weiter helfen, denn wie ich den Code auch dreh und wende ich bekomme immer eine der beiden Meldungen.
Danke
Verfasst: Mittwoch 11. Juli 2007, 17:06
von BlackJack
Erst bindest Du `test` an ``pointer(c_ulong())`` und ein paar Zeilen weiter dann an `rxEventHandle`. Damit hat das erste binden von `test` absolut keinen Effekt. Es sieht so aus, als wenn Du das für eine Deklaration hältst.
Du musst das Ergebnis des ersten Aufrufs irgendwie entsprechend umwandeln. Also zum Beispiel herausfinden wie man aus einem `PyHANDLE` die "rohe" Zahl heraus bekommt um damit einen Pointer auf diese Zahl in `ctypes` zu basteln.
Verfasst: Freitag 13. Juli 2007, 08:25
von HarryPython
Danke für den Tip
Ich geh mal davon aus das in dem PyHandle die erste Zahl die Adresse ist und die Zweite die Id ist. Mit hash und int kann man die Zahlen rausholen.
Hab das jetzt so gemacht:
Code: Alles auswählen
class blabla(object):
test.rxEventHandle = win32event.CreateEvent(None, False, False, None)
h= hash(test.rxEventHandle) #Id aus dem PyHandle
i= int(test.rxEventHandle) #Adresse aus dem PyHandle
hallo=blabla()
vErr = candll.ncdSetNotification(port, hallo.h, 1)
Bekomme jetzt keine Fehlermeldung mehr.
Bezüglich der Zuweisung. Da hast Recht dass war natürlich Müll.
So besser??:
Code: Alles auswählen
class test(ctypes.Structure):
_fields_ = [("rxEventHandle", c_ulong)]