Mithilfe von Python-Ctypes zu übergeben struct Zeiger auf eine DLL-Funktion
Ich bin versucht, Zugriff auf eine Funktion in einer DLL-Datei mit Python-ctypes. Die mitgelieferte Beschreibung der Funktion finden Sie weiter unten.
Prototype: Picam_ConnectDemoCamera( PicamModel model,
const pichar* serial_number,
PicamCameraID* id )
Description: Virtually connects the software-simulated 'model' with 'serial_number'
and returns the camera id in `_id_`
Notes: `_id_` is optional and can be null
Die Funktion verweist auf ein paar Typen von Variablen in der DLL definiert. Diese Variablen werden im folgenden beschrieben
PicamModel
Type: enum
Description: The camera model.
PicamCameraID
Type: Struct
- PicamModel model: _model_ is the camera model
- PicamComputerInterface computer_interface: computer_interface is the method of
communication
- pichar sensor_name [PicamStringSize_SensorName]: sensor_name contains the name of
the sensor in the camera
- pichar serial_number [PicamStringSize_SerialNumber]: serial_number contains the
unique serial number of the camera
Beachten Sie, dass'pichar' definiert ist, in einer der angegebenen header-Dateien wie folgt:
typedef char pichar; /* character native to platform
Dies scheint einfach, aber ist das nicht für mich aus irgendeinem Grund.
Mein Verständnis ist wie folgt: ich gebe die Funktion von drei Variablen:
1) eine model
, das ist wirklich eine enum
. Ich hab mir sagen lassen, dass python-ctypes nicht inhärent unterstützen Enumerationen, und so leite ich es ein integer, 2, die Karten zu einem bestimmten Modell geben.
2) einen Zeiger auf die Seriennummer (ich kann diese up: eine beliebige Zeichenkette)
3) Einen Zeiger auf PicamCameraID
, Typ einer Variablen definiert, die innerhalb der DLL, auf der Grundlage der struct
Typ
Nach Lesen, SO fand ich ein paar gute Ansatzpunkte, aber bin immer noch läuft Pech gehabt. Hier ist mein bestes bisher
def pointer(x):
PointerToType = ctypes.POINTER(type(x))
ptr = ctypes.cast(ctypes.addressof(x), PointerToType)
return ptr
class PicamCameraID(ctypes.Structure):
pass
PicamCameraID._fields_=[("model",ctypes.c_int),
("computer_interface",ctypes.c_int),
("sensor_name",ctypes.c_char_p),
("serial_number",ctypes.c_char_p)]
myid = PicamCameraID()
model = ctypes.c_int(2)
serialnum = ctypes.c_char_p('asdf')
print picam.Picam_ConnectDemoCamera(model, pointer(serialnum), ctypes.byref(myid))
Wie Ihr hoffentlich seht, ich bin beim erstellen der Variablen-Typ, entspricht der PicamCameraID
struct in der DLL definiert. Meine intuition war, mit ctypes.pointer
Befehl zum Verweis auf diese wenn man das argument der Funktion, aber ich fand Indikationen zu verwenden ctypes.byref
statt anderswo.
Den code ohne Fehler ausgeführt wird (gibt 0 zurück), aber ich bekomme unterschiedliche Ergebnisse wenn ich versuche, Zugriff auf die Eigenschaften des struct PicamCameraID
:
myid.model
gibt "2" das ist toll das ist, was ich angegeben
myid.computer_interface
gibt "1" und das ist gut
ABER das problem ist myid.serial_number
gibt
Traceback (most recent call last): File "<pyshell#28>", line 1, in
<module>
myid.serial_number ValueError: invalid string pointer 0x2820303031207820
sowie myid.sensor_name
gibt:
Traceback (most recent call last): File "<pyshell#29>", line 1, in
<module>
myid.sensor_name ValueError: invalid string pointer 0x3034333120563245
Für einige Grund diese Saiten nicht richtig aufgefüllt?
Irgendwelche Ideen würde sehr geschätzt, ich bin ein Neuling auf python-ctypes (und c)
Freundlichen GRÜßEN
Neben 1. Juni 2013
typedef enum PicamStringSize {
PicamStringSize_SensorName = 64,
PicamStringSize_SerialNumber = 64,
PicamStringSize_FirmwareName = 64,
PicamStringSize_FirmwareDetail = 256 } PicamStringSize;
typedef struct PicamCameraID {
PicamModel model;
PicamComputerInterface computer_interface;
pichar sensor_name[PicamStringSize_SensorName];
pichar serial_number[PicamStringSize_SerialNumber];
} PicamCameraID;
- Was ist
pichar
? Wie man die Größe der string wird bestimmt? Was passiert, wenn Sie passierenserialnum
direkt und ohnepointer()
nennen? - J. F. -- vielen Dank für die Beantwortung. Meine header-Datei sagt mir Folgendes: typedef char pichar; /* Zeichen nativen Plattform, in anderen Worten, ich denke es ist einfach nur re-mapping der char?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre definition von PicamCameraID Struktur ist falsch:
sensor_name
undserial_number
sind arrays:Es scheint das zweite argument ist nur ein string, so brauchen Sie nicht zu gelten
pointer()
zu. Hier ist diectypes
Prototyp fürPicam_ConnectDemoCamera()
Funktion:Nennen es:
Wahrscheinlich sind Sie nicht die Eingabe der genauen Struktur Felder in der gleichen Reihenfolge. Wenn Sie das nicht können, dann erhalten Sie in der Regel zufällige Daten oder Zugriffsfehler. Zugriff auf eine Bibliothek mit ctypes, müssen Sie in der Regel sehen Sie in den header (.h-Datei) zu kopieren, die genaue Struktur und definition. Nutzen Sie alternativ cffi mit ffi.überprüfen Sie (), wenn Sie nicht wollen, zu hängen, das genaue layout.