C-Struktur aus named pipe lesen

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
Antworten
UweA
User
Beiträge: 9
Registriert: Dienstag 30. Juni 2020, 08:50

Ich möchte eine named pipe zur Kommunikation zwischen einem C-Program und Python verwenden.
Die Kommunikation mit Strings läuft soweit.
Nun möchte ich eine Struktur an Python übergeben. Und da fängt es an, nicht mehr zu funktionieren.

Die C-Seite sieht so aus:

Code: Alles auswählen

typedef struct {
	int a;
	int b;
} testStruct;

...

testStruct ts;
ts.a = 65;
ts.b = 66;
write(fd, &ts, sizeof ts);
...
Und auf der Pythonseite:

Code: Alles auswählen

class testStruct:
    a = 0
    b = 0
....

    data:testStruct = os.read(fifo, 4)
    print("Read", data.a, " ", data.b)
Die Fehlermeldung, die ich erhalte lautet:
File "reader.py", line 27, in <module>
print("Read", data.a, " ", data.b)
AttributeError: 'bytes' object has no attribute 'a'
Mit "data:testStruct = os.read(fifo, 4)" wollte ich eine Typkonvertierung erzwingen. Das scheint aber wohl so nicht zu funktionieren.

Hat jemand einen Vorschlag, wie ich hier weiterkomme?
nezzcarth
User
Beiträge: 1631
Registriert: Samstag 16. April 2011, 12:47

Ich würde die Daten als Json oder msgpack serialisiert austauschen. Der Doppelpunkt darf übrigens in regulärem Python nicht in Namen vorkommen. (EDIT: Ach, das ist bestimmt wieder irgendwas mit Type Annotations ... )
Benutzeravatar
__blackjack__
User
Beiträge: 12984
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@UweA: Das ist nicht wirklich portabel einfach so C-Strukturen zu schreiben. Das lässt sich nur auf der gleichen Plattform mit dem gleichen C-Compiler tatsächlich ”sicher” wieder lesen, weil man ja gar nicht weiss wie die Daten in dem `struct` abgelegt sind. Also wie viele Bits ein `int` hat, ob und wie viel ”padding” beim `struct` zwischen den beiden Werten steckt, und ob die `int`-Werte big endian oder little endian gespeichert sind.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

Typannotationen definieren keine Typen, sondern geben nur einen (hier falschen) Hinweis, welchen Typ eine Variable hat. Und os.read liefert bytes zurück, also ist an data ein Objekt vom Typ bytes gebunden.
Die Zeiten, in denen int`s 16bit waren sind schon eine Weile her. Besser ist es also, eine Bibliothek zu benutzen, die sicher Structuren definiert, ich werfe noch protobuf in den Ring.
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Kann es sein, dass du eigentlich ctypes benutzen willst? Beim letzten mal zumindest ging es dir doch noch um Einbettung?
UweA
User
Beiträge: 9
Registriert: Dienstag 30. Juni 2020, 08:50

Ich habe mir alle Lösungen mehr oder minder intensiv angesehen: ctypes, JSON und protobuf.
Im Moment tendiere ich zu protobuf. Mit ctypes scheint es nur möglich zu sein, C-Strukturen in Python zu verwenden. Ich benötige aber auch den anderen Weg.
JSON ist mir zu aufwendig, weil ich es mit ziemlich umfangreichen Strukturen zu tun habe.
protobuf scheint am universellsten zu sein. Es ist jetzt nämlich auch noch Java als Schnittstelle hinzugekommen.
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich weiß nicht so genau was “der andere weg ist”. Aber protobuf ist grundsätzlich eine gute Idee.
UweA
User
Beiträge: 9
Registriert: Dienstag 30. Juni 2020, 08:50

"der andere Weg" ist von Python zu C bzw. nun auch noch von Python zu Java.
Antworten