Typ HANDLE in Python übersetzen

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
HarryPython
User
Beiträge: 60
Registriert: Freitag 8. Juni 2007, 07:39

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
BlackJack

Da wirst Du herausfinden müssen, was für ein Typ `HANDLE` ist. Irgendwo muss das ja definiert sein.
HarryPython
User
Beiträge: 60
Registriert: Freitag 8. Juni 2007, 07:39

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.
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Ich bin in der Visual-Studio-Lib auf das hier gestoßen
win32.h hat geschrieben:

Code: Alles auswählen

typedef int             HANDLE;
HarryPython
User
Beiträge: 60
Registriert: Freitag 8. Juni 2007, 07:39

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.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Wieso? Meist ist das Handle ein Pointer zu einer OS-internen Struktur. Und solch ein Pointer kann problemlos zu einem Integer gecastet werden.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

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"
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

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'
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Integer != int.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
HarryPython
User
Beiträge: 60
Registriert: Freitag 8. Juni 2007, 07:39

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
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.
HarryPython
User
Beiträge: 60
Registriert: Freitag 8. Juni 2007, 07:39

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)]
Antworten