C++ Funktion in Python umsetzen

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
Antworten
Quen
User
Beiträge: 4
Registriert: Donnerstag 17. Juni 2010, 08:26

Hi zusammen!

Ich nutze eine Software, die Daten über einen Socket streamt. Diese Daten muss ich nun in einer Anwendung lesen, die mit Python (2.6) arbeitet. Leider habe ich kaum Erfahrung mit Python und daher etwas Probleme, die Datenpakete richtig auszulesen. Der streamenden Software lag ein Beispiel-Code zum Empfangen der Daten in C++ bei, und nun versuche ich, das Ganze in Python zu "übersetzen".
Den Socket konnte ich bereits erfolgreich belegen und auch Pakete empfangen, jedoch scheinen diese "gepackt" zu sein und ich empfange nur Kauderwelsch. Ich habe in dem C++ Beispiel eine Unpack Funktion gefunden, jedoch habe ich große Probleme, diese in Python umzusetzen.
Es wäre toll, wenn mir jemand auf die Sprünge helfen könnte, wie man das am besten handeln könnte.
Hier die grundlegenden Ausschnitte der Funktion:

Code: Alles auswählen

void Unpack(char* pData)
{
    char *ptr = pData;
    printf("Begin Packet\n-------\n");

    // message ID
    int MessageID = 0;
    memcpy(&MessageID, ptr, 2); ptr += 2;
    printf("Message ID : %d\n", MessageID);

    // size
    int nBytes = 0;
    memcpy(&nBytes, ptr, 2); ptr += 2;
    printf("Byte count : %d\n", nBytes);

    // Markerset name
    char szName[256];
    strcpy_s(szName, ptr);
    int nDataBytes = (int) strlen(szName) + 1;
    ptr += nDataBytes;
    printf("Model Name: %s\n", szName);

...
Freue mich über jede Hilfe!
Vielen Dank schonmal,
Quen
Zuletzt geändert von Quen am Montag 21. Juni 2010, 11:52, insgesamt 1-mal geändert.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo und willkommen im Forum!

Dann zeig doch mal, wie deine bisherige unpack-Version aussieht. Die lässt sich sicher anpassen.

Sebastian
Das Leben ist wie ein Tennisball.
Quen
User
Beiträge: 4
Registriert: Donnerstag 17. Juni 2010, 08:26

Danke für den Willkommensgruß :)

Die Unpack-Funktion habe ich in Python noch gar nicht hinbekommen. Da stehe ich irgendwie, wie der Ochs' vorm Berg. :?
Ich habe bisher leider keine Idee, wie ich das überhaupt vom Konzept her angehen muss, da es in Python ja offensichtlich keine Zeiger gibt(?) und ich auch eine memcpy() entsprechende Funktion noch nicht gefunden habe.

Bin wie gesagt, noch sehr unerfahren mit Python.
lunar

Um Binärdaten auszulesen, bietet sich das struct-Modul an.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Die gezeigte C-Funktion ist hochgradig unportabel und es hängt total vom Betriebssystem und Compiler ab, was da nach "pData" geschrieben wird.

Es schreibt die ersten zwei Bytes eines int. Doch wie viele Bytes hat der? C schreibt hier nichts vor, doch typisch ist zwischen 2 und 8 Bytes. Auch kann der als LSB oder MSB (aka little endian und big-endian bzw. network-byte-order) abgelegt sind. In letzterem Fall wird wahrscheinlich nur 0 geschrieben, wenn man annimmt dass ein int 32 bit als 4 Bytes hat und eine Message ID relativ klein ist. Gleiches gilt für die Länge. Anhand von `strcpy_s` schließe ich, dass das ein Beispiel für Microsoft C++ ist, denn das ist keine Standard-C-Funktion. Das würde LSB bedeuten.

Code: Alles auswählen

import struct
struct.pack("<HH%ss" % (len(name) + 1), message_id, size, name)

# das hier gefällt mir nicht wirklich, denn ich kann den 0-terminierten String nicht mit unpack lesen
message_id, size = struct.unpack("<HH", data[:4])
name = data[4:].split('\0', 1)[0]
Stefan
Quen
User
Beiträge: 4
Registriert: Donnerstag 17. Juni 2010, 08:26

Hi Stefan,

wow! Vielen Dank für die Antwort!
Wie ich schon geschrieben hatte, bin ich ein recht unerfahrener Programmierer. Daher hatte ich mir an der struct.unpack Funktion einfach die Zähne ausgebissen, da ich nicht verstanden habe, wie sie funktioniert und wie man die Formate angeben muss. Auch jetzt bin ich mir grad nicht so sicher, ob ich verstehe, was ich hier tue, aber dank deines kleinen Beispiels konnte ich direkt mehrere Werte korrekt auslesen!
Zuvor hatte zufällig die ord() Funktion gefunden, und damit etwas getestet. Damit habe ich immerhin eine byte-weise Ausgabe erhalten:
http://img38.imageshack.us/img38/1273/perbyte.jpg
Da kann man "erraten", was wie viele Bytes hat.

Insgesamt ist die Unpack() aus dem Sample noch wesentlich komplizierter, da ich jetzt gerade mal nur die Daten eines einzelnen Objekts übertrage. Später sollen die Daten eines ganzen Skeletts übertragen werden. Aber Dank dir kann ich mich da jetzt hoffentlich durchfummeln!

Nochmal danke :-)
BlackJack

Vielleicht ist construct auch etwas für Dich. Das ist bei komplexeren Formaten vielleicht einfacher als `struct`.
Quen
User
Beiträge: 4
Registriert: Donnerstag 17. Juni 2010, 08:26

Danke für den Hinweis, BlackJack. Werde mir den parser mal ansehen. Da es mit 'struct' im Moment alles klappt, werde ich erstmal da genauer reinschauen, und etwas ins Detail gehen. Habe mir die 'construct' Seite aber gleich mal gebookmarked :)
Antworten