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 passieren serialnum direkt und ohne pointer() 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?
InformationsquelleAutor Joe | 2013-06-01
Schreibe einen Kommentar