[ctypes] Pointer auf Struktur als Argument

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.
Jaspar
User
Beiträge: 12
Registriert: Mittwoch 18. März 2009, 17:42

Hallo Community,

ich habe eine Frage zur korrekten Adaption einer C-Struktur, sowie dem entsprechenden Funktionsaufruf der API-Funktion.

Die Datenstruktur in C sieht folgendermaßen aus:

  • Code: Alles auswählen

    typedef struct{
        unsigned short dasChan
        float* temp
    } tcMuxRead
    
Es gibt nun eine API-Funktion welche einen Pointer auf obige Struktur als Argument übergeben bekommt.

Meine bisherige Adaption der C-Struktur in Python sieht folgendermaßen aus:
  • Code: Alles auswählen

    class TCMUXREAD(ctypes.Structure):
            _fields_ = [("dasChan", ctypes.c_ushort),
                        ("temp", ctypes.c_float * 1)]
    
Ich erzeuge eine Instanz der Klasse TCMUXREAD indem ich folgendes schreibe: Wenn ich nun aber die API-Funktion aufrufe und die Klassen-Instanz mittels ctypes.byref(tcMuxRead) übergebe bekomme ich einen AccessViolation-Fehler.
Ich bin für jede Hilfe dankbar.



Liebe Grüße,

Jas
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Code: Alles auswählen

class TCMUXREAD(ctypes.Structure):
        _fields_ = [("dasChan", ctypes.c_ushort),
                    ("temp", ctypes.POINTER(ctypes.c_float))]
Und so funktionierts auch nicht?
Das ctypes.byref kannst du sein lassen, sollte ok sein.

Gruss
Jaspar
User
Beiträge: 12
Registriert: Mittwoch 18. März 2009, 17:42

Hallo rayo,

ich kann Deinen Vorschlag erst morgen ausprobieren.
Ich melde mich dann. Vielen Dank schon mal.
Jaspar
User
Beiträge: 12
Registriert: Mittwoch 18. März 2009, 17:42

Hallo rayo,

ich habe Deine Idee gerade einmal ausprobiert.
Leider ist das Ergebnis unverändert.

Ich erhalte folgende Fehlermeldung:

WindowsError: exception: access violation reading 0x0000000C
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Hast du eine Dokumentation der API?
Vielleicht musst du das Feld temp mit einer bestimmten Anzahl floats erstellen.

Z.B. versucht er auf das 3. Element zuzugreifen und es existiert gar nicht.

Sonst kann ich mir nichts vorstellen.

Gruss
Jaspar
User
Beiträge: 12
Registriert: Mittwoch 18. März 2009, 17:42

Heyho,

inzwischen bin ich einen Schritt weiter.
Wenn ich die Struktur wie ursprünglich definiere:
  • Code: Alles auswählen

    class TCMUXREAD(ctypes.Structure):
            _fields_ = [("dasChan", ctypes.c_ushort),
                        ("temp", ctypes.c_float * 1)]
    
Und dann die API-Funktion folgendermaßen aufrufe:
Wobei p_tcMuxRead = ctypes.pointer(tcMuxRead) ist, erhalte ich keinerlei Fehlermeldung mehr. Allerdings ist dann der Wert von p_tcMuxRead.contents.temp[0] immer gleich 0.0. Das ist aber nachweislich nicht korrekt. Es gibt eine C-Beispielapplikation die die gleiche API-Funktion verwendet und korrekte Temperaturwerte liefert.

Ich bin nach wie vor sehr dankbar für Hilfestellungen.



Liebe Grüße,

Jas
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Kannst du mal das C Beispiel mal hier einfuegen: http://paste.pocoo.org/

Gruss
Jaspar
User
Beiträge: 12
Registriert: Mittwoch 18. März 2009, 17:42

Hey,

den gesamten Code, oder nur den Funktionsaufruf?

Der gesamte Code ist relativ umfangreich.

[Edit 1] Ich hab mal einen Auszug eingefügt.
[Edit 2] Paste #108614
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Der Datentyp von ptTCMuxRead waere noch interessant. Also das Struct selber (ist ja groesser als deins vom 1. Post) und wie ptTCMuxRead definiert wurde.

Code: Alles auswählen

class TCMUXREAD(ctypes.Structure):
        _fields_ = [("dasChan", ctypes.c_ushort),
                    ("temp", ctypes.POINTER(ctypes.c_float))]

temp = ctypes.c_float()
ptTCMuxRead = TCMUXREAD()
TCMUXREAD.temp = ctypes.pointer(temp)

TCMuxRead(driverHandles[0], ctypes.byref(ptTCMuxRead))
Vielleicht so?

Gruss
Jaspar
User
Beiträge: 12
Registriert: Mittwoch 18. März 2009, 17:42

Hey,

static PT_TCMuxRead ptTCMuxRead

Code: Alles auswählen

typedef struct tagPT_TCMuxRead
{
    USHORT      DasChan;
    USHORT      DasGain;
    USHORT      ExpChan;
    USHORT      TCType;
    USHORT      TempScale;
    FLOAT far   *temp;
} PT_TCMuxRead
[Edit 1] Dein letzter Vorschlag führt wieder zu einer access violation writing 0x00000000
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Code: Alles auswählen

class TCMUXREAD(ctypes.Structure):
        _fields_ = [("dasChan", ctypes.c_ushort),
                    ("dasGain", ctypes.c_ushort),
                    ("expChan", ctypes.c_ushort),
                    ("tCType", ctypes.c_ushort),
                    ("tempScale", ctypes.c_ushort),
                    ("temp", ctypes.POINTER(ctypes.c_float))]

temp = ctypes.c_float()

ptTCMuxRead = TCMUXREAD()
ptTCMuxRead.dasGain = gwDasGain;
ptTCMuxRead.expChan = gwExpChl;
ptTCMuxRead.tCType = gwTcType;
ptTCMuxRead.tempScale = gwTempScale;
ptTCMuxRead.temp = ctypes.pointer(temp)

TCMuxRead(driverHandles[0], ctypes.byref(ptTCMuxRead))
So sollte das meiner Meinung nach korrekt sein.

Ist LPT_TCMuxRead einfach ein Pointer auf TCMUXREAD?

Gruss
Jaspar
User
Beiträge: 12
Registriert: Mittwoch 18. März 2009, 17:42

Das führt nach wie vor zu einer access violation writing 0x00000000
rayo hat geschrieben: Ist LPT_TCMuxRead einfach ein Pointer auf TCMUXREAD?
Ja.
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Dann kann ich dir auch nicht weiter helfen.

Vielleicht kannst du bei der ctypes mailing liste fragen.

Gruss
Jaspar
User
Beiträge: 12
Registriert: Mittwoch 18. März 2009, 17:42

Heyho,

vielen Dank für die Hilfe.

Ich werde mal schauen, ob ich bei der Mailingliste weitere Hilfe finde.



Liebe Grüße,

Jas
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Etwas komisch ist ja der Far-Pointer auf ein Float. Ist das etwa eine 16-Bit-Bibliothek?
MfG
HWK
Jaspar
User
Beiträge: 12
Registriert: Mittwoch 18. März 2009, 17:42

Hallo HWK,

ich denke nicht, aber prizipiell sollen wohl auch 16-Bit Systeme unterstützt werden.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Ist far denn bei 32-Bit-Compilern üblich? Wenn es wirklich eine 16-Bit-Lib ist, muss ja auch der Zeiger anders aussehen. Ich glaube nicht, dass ctypes das automatisch anpasst?
MfG
HWK
Jaspar
User
Beiträge: 12
Registriert: Mittwoch 18. März 2009, 17:42

Nein, soweit ich weiß ist far nicht üblich bei 32-Bit Systemen. Die Bibliothek kapselt aber wohl über Präprozessordirektiven das zugrundeliegende Betriebssystem und ersetzt das Schlüsselwort far dann durch einen Leerstring.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Nur um sicher zu gehen: driverHandles[0] ist auch ein entsprechender ctypes-Typ wie c_short?
MfG
HWK
Jaspar
User
Beiträge: 12
Registriert: Mittwoch 18. März 2009, 17:42

driverHandles[0] ist ein c_long.
Antworten