hallo,
ich (python-newbie) möchte eine externe hardware über python ansprechen. via ctypes() habe ich die dll des geräts eingebunden, entsprechende teilefolge lassen erahnen, dass die kommunikation mit der hardware (oder zumindest der dll) funktioniert.
ich möchte jetzt einen befehl ausführen, der in der SDK-Dokumentation des geräts beschrieben ist. mit dem befehl muss ich einen parameter übergeben. laut dokumentation ist dieser parameter vom typ ZebDevice* (description: Pointer to device, size: 4 byte). wie kann ich jetzt einen solchen pointer erstellen? soweit ich weiß, muss man doch in python nicth deklarieren.
muss ich dafür eine klasse ZebDevice* erstellen?
vg, mario.
variablendeklaration für externe hardware
Wenn Du von Python aus auf Felder von so einem `ZebDevice` zugreifen willst/musst, dann müsstest Du die Struktur mit `ctypes`-Objekten nachbauen. Wenn das nur ein Pointer ist, den man bei der API herum reicht, geht auch ein `ctypes.c_void_p`.
Das ist eine Klasse die den C-Datentyp `void*` modelliert. Die Klasse kann man verwenden, wo `ctypes` "C-Typen" erwartet, und Instanzen davon wo `void*` als Werte erwartet werden.
Dokumentation gibt's da wo die Standardbibliothek halt dokumentiert ist: http://docs.python.org/lib/module-ctypes.html
Dokumentation gibt's da wo die Standardbibliothek halt dokumentiert ist: http://docs.python.org/lib/module-ctypes.html
also ich habs jetzt mal mit
versucht. wenn ich dann den befehl aufrufe (ctypes.windll.zebsdk.ZebDeviceManager_GetDevice(dev)) bekomme ich eine Access violation exception. mit admin rechten kann das aber nicths zu tun haben (habe die konsole als admin gestartet)...
Code: Alles auswählen
dev=ctypes.c_void_p()
Damit hast Du einen Null-Pointer erstellt. Das entspricht in C etwa:
Die Funktion will also einen Pointer auf eine `ZebDevice`-Struktur um diese mit Daten zu füllen. Da kann man dann nicht einfach einen NULL-Pointer, also einen "Pointer auf nichts", übergeben. Die Funktion versucht damit an Adresse 0 etwas zu schreiben was zu einem Speicherzugriffsfehler führt.
Also musst Du die Struktur in `ctypes`-Objekten nach bauen, eine Instanz erstellen und einen Pointer darauf übergeben.
Code: Alles auswählen
void *dev = NULL;
ZebDeviceManager_GetDevice(dev);
Also musst Du die Struktur in `ctypes`-Objekten nach bauen, eine Instanz erstellen und einen Pointer darauf übergeben.
hmm, aber woher weiß ich was ich da "bauen" soll`? in der sdk-dokumentation gibt es etwas beispielcode. da steht "typedef struct {} ZebDevice;" weiß nicth welche sprache das sein soll aber sieht nicth so aus als gäbe es für das device irgendwelche methoden oder attribute...
Das sieht nach C aus. Also wird es auch irgend wo Header-Dateien geben, wo diese Struktur deklariert ist. Wenn ``ZebDeviceManager_GetDevice()`` wirklich einen Pointer auf so eine Struktur haben will, muss man mehr haben als eine leere Struktur als Deklaration oder es muss einen anderen Weg geben einen Pointer auf so eine Struktur von der DLL zu bekommen.
naja, in der documentation steht, 'a handle to the [...] device must be retrieved from the SDK. Procedure: ZebDeviceManager_GetDevice(ZebDevice** device);'
also die wollen damit sagen diese methode gibt das device zurück, aber irgendwie muss man doch auch ein device als parameter übergeben.
bei der beschreibung des befehls ..._GetDevice(ZebDevice** device) steht "device: pointer to a pointer which receives the device handle." ich verstehe das nicht. dann müsste es doch auch eine methode geben, um den 'pointer to a pointer' zu bekommen?
also die wollen damit sagen diese methode gibt das device zurück, aber irgendwie muss man doch auch ein device als parameter übergeben.
bei der beschreibung des befehls ..._GetDevice(ZebDevice** device) steht "device: pointer to a pointer which receives the device handle." ich verstehe das nicht. dann müsste es doch auch eine methode geben, um den 'pointer to a pointer' zu bekommen?
ich habe von python aus ein setup fenster gestartet bekommen. ein setup fenster für das gerät. "to setup the parameters of the selected device click 'setup''. ich kann leider kein device auswählen, weil an den rechner keins angeschlossen ist (nur SDK installiert). ich werde das mal ausprobieren an dem rechner an dem das gerät angeschlossen ist, und melde mich dann in einiger zeit wieder.
vielen dank für die bisherige hilfe schonmal!
vielen dank für die bisherige hilfe schonmal!
-
- User
- Beiträge: 773
- Registriert: Mittwoch 5. November 2003, 18:06
- Wohnort: Schweiz
- Kontaktdaten:
Probier mal folgendes:
Da ja steht ein Pointer auf einen Pointer will die Funktion wahrscheinlich ein solches Struct erstellen und den Pointer darauf in dev schreiben.
Gruss
Code: Alles auswählen
import ctypes
dev=ctypes.c_void_p()
ZebDeviceManager_GetDevice(ctypes.byref(dev))
Gruss
wow! das funktioniert! zumindest teilweise. es gibt keine fehlermeldung mehr. die antwort ist eher schlicht: 0import ctypes
dev=ctypes.c_void_p()
ZebDeviceManager_GetDevice(ctypes.byref(dev))
wenn der ..._GetDevice()-aufruf eine 0 zurückgibt, heisst das, dass ein fehler vorliegt. die ..._GetLastError() funktion gibt ein "Device '' not found, please execute the hardware setup" zurück. d.h. jetzt muss ich wirklich das gerät anschliessen und das setup ausführen.
vielen dank!
[was hab ich denn da gemacth? byref(dev) ist ein pointer auf die leere klasse dev??]
-
- User
- Beiträge: 773
- Registriert: Mittwoch 5. November 2003, 18:06
- Wohnort: Schweiz
- Kontaktdaten:
Nein du übergibts dev einfach als Referenz (byref = by reference), d.h. wenn die Funktion selbst dev ändert, verändert sich auch dein dev, da es der gleiche Pointer ist.
Eingentlich erstellt das einen Pointer auf dev und da dev ein void-Pointer ist übergibst du einen Pointer auf einen Pointer auf eine beliebige Sache (hier das Struct).
Gruss
Eingentlich erstellt das einen Pointer auf dev und da dev ein void-Pointer ist übergibst du einen Pointer auf einen Pointer auf eine beliebige Sache (hier das Struct).
Gruss