convert frage von c nach python

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.
Antworten
_blubber_
User
Beiträge: 6
Registriert: Montag 3. August 2009, 19:15

wie kann ich folgendes in python abbilden

unsigned int tag;
unsigned char buf[3];

assert(tag == 0x23);

buf[0] = 0x04;
buf[1] = 0x13;
buf[2] = 0x08;
buf[3] = 0x00;

buf[0] = (tmp >> 4) & 0xff;
buf[1] = (tmp >> 0) & 0xff;
buf[2] = (len >> 4) & 0xff;
buf[3] = (len >> 0) & 0xff;


das ganze ist für eine kommunikation über die rs232
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Mit `buf = [0,0,0,0]` statt deines falschen, um eins zu kleines C-Array, funktioniert das doch bereits wie gewünscht. Man kann jetzt natürlich die ; und die Klammern bei assert weglassen.

Stefan
_blubber_
User
Beiträge: 6
Registriert: Montag 3. August 2009, 19:15

hmm irgendwie raff ich das nicht ganz mit python

Code: Alles auswählen

import socket
uds = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
uds.connect(("/tmp/q_socket"))
buf = [0,0,0,0,0,0,0]
buf[0] = hex((0x0001 >> 8)& 0xff)
buf[1] = hex((0x0001 >> 0)& 0xff)
buf[2] = hex((0x03 >> 8)& 0xff)
buf[3] = hex((0x03 >> 0)& 0xff)
buf[4] = hex(0x01)
buf[5] = hex(0x02)
buf[6] = hex(0x03)
uds.send(str(buf))
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Füge zwischen Zeile 12 und 13 mal ein

Code: Alles auswählen

print str(buf)
ein, dann kommst du schon dahinter ;-) Als nächstes suchst du dann nach der join-Methode von Strings.

Die Aufrufe der "hex"-Funktion sind hier übrigens vollkommen überflüssig.
Konstanten sind auch keine schlechte Erfindung ;-)
Und bist du dir sicher, dass du nach rechts shiften möchtest? Du produzierst auf jeden Fall zwei Nullen.
Das Leben ist wie ein Tennisball.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

_blubber_ , wenn du Python 2.6 oder 3.1 hast, nimm doch einfach `bytearray`. Ich glaube, das kann man direkt an send() übergeben. Andernfalls muss da noch ein `str` drum rum. Ansonsten ist es `chr` statt `hex`, wenn du aus einer Zahl (mit den Codepoint des Zeichens) ein Zeichen machen willst.

`Bytearray` will eine Liste von Zahlen haben, die dann als Bytes interpretiert werden: `bytearray([1, 2, 3])

In 3.1 geht direkt `bytes([1, 2, 3])`.

Stefan
_blubber_
User
Beiträge: 6
Registriert: Montag 3. August 2009, 19:15

ich habe leider nur Python 2.5.1
Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

Für das was du vorhast ist evtl. das struct Modul besser geeignet:

Code: Alles auswählen

>>> struct.pack("BBI", 1, 2, 1<<4)
'\x01\x02\x00\x00\x10\x00\x00\x00'
MFG HerrHagen
BlackJack

@EyDu: Die Richtung des Verschiebens ist egal -- mit der Und-Verknüpfung danach würde auch verschieben in die andere Richtung letztendlich 0en produzieren.
_blubber_
User
Beiträge: 6
Registriert: Montag 3. August 2009, 19:15

ich werd mit python ned warm in c funktioniert das

Code: Alles auswählen

#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <unistd.h>

#define Q_SOCKET "/tmp/q_socket"

int main() {
	
	int sockfd;
	int i;
	unsigned char buf[7];
	unsigned char rbuf[4];

	buf[0] = (0x001 >> 8) & 0xff;
	buf[1] = (0x001 >> 0) & 0xff;
	buf[2] = (0x03 >> 8) & 0xff;
	buf[3] = (0x03 >> 0) & 0xff;
	buf[4] = 0x01;
	buf[5] = 0x02;
	buf[6] = 0x03;
	
	for (i=0; i < 7; i++){
		printf("buf: %#x\n", (int)buf[i]);
	}

	struct sockaddr_un addr;
	addr.sun_family = AF_UNIX;
	strcpy(addr.sun_path, Q_SOCKET);
	sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
	if (connect(sockfd, (const struct sockaddr *)&addr, SUN_LEN(&addr)))
	{
		printf("ERROR: connect\n");
		return 0;
	}
	write(sockfd, buf, sizeof(buf));
	read(sockfd, rbuf, 4);
	for (i=0; i < 4; i++){
		printf("rbuf: %#x\n", (int)rbuf[i]);
	}
	close(sockfd);
	return 0;
}
mit folgender ausgabe:
buf: 0
buf: 0x1
buf: 0
buf: 0x3
buf: 0x1
buf: 0x2
buf: 0x3
rbuf: 0
rbuf: 0x1
rbuf: 0
rbuf: 0xc
BlackJack

@_blubber_: Und wo genau liegt jetzt das Problem? Ist ja schön, dass Du uns immer C-Quelltext zeigst, aber das der *so* nicht in Python funktioniert, sollte doch eigentlich klar sein. Ist ja schliesslich C und nicht Python.

Zeig doch lieber mal wie Dein Python Quelltext aussieht, und was da nicht funktioniert.

Hast Du das Tutorial in der Python-Dokumentation schon durchgearbeitet, um Dir die Grundlagen draufzuschaffen!?

Ist Dir klar, das Python-Zeichenketten im Grunde, wie bei C, Byteketten sind? Hast Du Dir angeschaut, welche Operationen es auf Zeichenketten gibt, und welche Funktionen zur Verfügung stehen, ohne das man etwas importieren muss (die sogenannten "Builtins")? Die Dokumentation zum `socket`-Modul gelesen? Mal in die vom `struct`-Modul geschaut?
Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

Hier ist mal der erste Teil deines Programms in Python umgesetzt.

Code: Alles auswählen

import socket 
import struct

uds = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 
uds.connect(("/tmp/q_socket")) 
buf = [(0x0001 >> 8) & 0xff,
       (0x0001 >> 0) & 0xff,
       (0x03 >> 8) & 0xff,
       (0x03 >> 0) & 0xff,
       0x01,
       0x02,
       0x03]
for index, byte in enumerate(buf):
    print "buf[%i]: %#x" % (index, byte)
buf = struct.pack("7B", *buf)
uds.send(buf)
Allerdings solltest du lieber mal verraten was du eigentlich vorhast. Dein Ziel sollte ja sein die Sprache Python zu lernen und nicht C in Python-Syntax zu schreiben. Dazu musst du aufhören zu versuchen C-Konstrukte 1:1 in Python übersetzen zu wollen und anfangen darüber nachzudenken, wie man das Problem in Python lösen würde. Dann wirst du sicher auch einiges verkürzen können. Evtl. gibt es für dein spezielles Problem auch schon ein fertiges Modul in der stdlib.

MFG HerrHagen
fhoech
User
Beiträge: 143
Registriert: Montag 9. April 2007, 18:26

Der C-Code ist darüber hinaus stellenweise reichlich umständlich. Warum wird da ein gleichbleibender Buffer über eigentlich überflüssige Byte-Shift Operationen zusammengestöpselt?
Das

Code: Alles auswählen

buf[0] = (0x001 >> 8) & 0xff;
buf[1] = (0x001 >> 0) & 0xff;
buf[2] = (0x03 >> 8) & 0xff;
buf[3] = (0x03 >> 0) & 0xff;
geht auch einfacher:

Code: Alles auswählen

buf[0] = 0x00;
buf[1] = 0x01;
buf[2] = 0x00;
buf[3] = 0x03;
In Python wäre das Erzeugen des Buffers entsprechend ein Einzeiler.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Wenn man den ersten Post ansieht, muss man vermuten, dass die Konstanten wohl nur als Beispiel gedacht waren. Sicher unsinnig ist aberMfG
HWK
_blubber_
User
Beiträge: 6
Registriert: Montag 3. August 2009, 19:15

so sorry das ich mich erst jetzt melde hatte inet probleme

1000 thx jetzt rennt alles bestens hatte probleme vom umstzen vom c syntax in python
_blubber_
User
Beiträge: 6
Registriert: Montag 3. August 2009, 19:15

eine frage habe ich noch ich mach ein

Code: Alles auswählen

self.uds = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.uds.connect(("/tmp/q_socket"))
self.uds.settimeout(2.0)
und bekomme als fehler
/usr/lib/python2.5/site-packages/twisted/internet/defer.py:328:_runCallbacks
<string>:1:settimeout
/usr/lib/python2.5/socket.py:141:_dummy
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ist das die ganze Fehlermeldung? Der Trace sollte eigentlich noch ein wenig länger sein.
Das Leben ist wie ein Tennisball.
farid
User
Beiträge: 95
Registriert: Mittwoch 8. Oktober 2008, 15:37

_blubber_ hat geschrieben:eine frage habe ich noch ich mach ein

Code: Alles auswählen

self.uds = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.uds.connect(("/tmp/q_socket"))
self.uds.settimeout(2.0)
und bekomme als fehler
/usr/lib/python2.5/site-packages/twisted/internet/defer.py:328:_runCallbacks
<string>:1:settimeout
/usr/lib/python2.5/socket.py:141:_dummy
Vermischst Du hier etwa Twisted und low-level Socket-API? Sowas kann ganz schnell schiefgehen. Nur so nebenbei eingeworfen... ;)
Antworten