Heinrich Geiger wrote:
> char build_ibus_message ( char Sender, char Receiver, char Message) {> [...]> Sender, Receiver und Message sind jeweils ein "array of chars".
Das ist doch schon gelogen! Alle drei Variablen sind schlicht char, nix
Array. Wenn Du Arrays übergeben willst, dann musst Du schon Zeiger auf
char als Parameter benutzen...
Außerdem ist ibus_message vom Typ unsigned char , die Funktionen
wollen aber char sehen, weshalb der Compiler zu Recht meckert, dass es
Vorzeichenkonflikte gibt.
Außerdem gibt es da noch ein Problem:
der Rückgabewert sollte wohl auch ein zeiger auf eine
Zeichenkette sein (char*).
In deinem Fall ist ibus_message aber ein lokales Array.
Wenn du einen Zeiger auf dieses Objekt zurückgibst, wird
der Zeiger ungültig, sobald die Funktion verlassen wird.
Verwende stattdessen ein lokales, als 'static' markiertes Array oder
gar eine globale Variable, auch wenn es nicht schön ist.
Zudem verwendest du unsigned char und char durcheinander.
Gruß
Daniel
Mit
> warning: passing argument 1 of 'strlen' makes pointer from integer> without a cast
will dir der Compiler sagen, daß strlen einen Zeiger erwartet, du ihm
aber einen Integer übergibst (char ist ein Integertyp).
Und mit
> warning: pointer targets in passing argument 1 of 'strcpy' differ in> signedness
will er dir sagen, daß ein ibus_message nicht, wie von strcpy verlangt,
ein Array aus char, sondern ein Array aus unsigned char ist.
Die Zeile ist immer noch faul
strcat (ibus_message, &length);
length ist kein String. strcat kann unter Umständen
einmal quer durch den Speicher jagen und alles was nicht 0 ist
an ibus_message[] anfügen. Da die Größe von ibus_message[]
nicht berücksichtigt wird sogar darüber hinaus. Und dann wird
es richtig nett.
Ein Integer-Typ (int, aber auch char) ist eine Zahl - was du brauchst
ist
eine Zeichenkette (zeiger auf ein char array), die die Darstellung der
Zahl enthält.
Wenn dir die Funktion itoa() zur verfügung steht,
kannst du sie verwenden, um eine Zahl in eine Zeichenkette
umzuwandeln.
1
...
2
/* Du musst sicher sein, dass nie Zahlen umgewandelt werden, die
3
mehr als 16 Stellen haben. Das sollte bei 32-bit immer gegeben sein. */
4
#define MAX_NUMBER_STR_LEN 16
5
/* Am besten keine absoluten Zahlen mitten im Code.
Beachte bitte:
- strncpy, strncat statt strcpy, strcat
Die maximale Länge von ibus_message wird geprüft.
-> Sicherheit vor Speicherüberläufen
Daumenregel: Nie die Varianten ohne 'n' verwenden!
- Wenn build_ibus_message ein zweites mal aufgerufen wird,
wird die erste message überschrieben.
Sauber und sicher kannst du build_ibus_message so verwenden:
Diese Funktion hat aber npaar Probleme:
1. Strlen ist zwar schön und gut, aber es bricht ab, sobald sie ein 0x00
"sieht", weil das bedeutet für sie Stringende. In meinem Fall ist aber
ein 0x00 zulässig.
Das würde bedeuten, dass ich immer wissen muss, wie lange meine
Netzdaten sind, dann kann ich sauber arbeiten.
Das Gleiche gilt auch für SizeOf, so viel ich weiss.
Alle Daten sind dexadzimal, nicht dezimal.
Hier mal ein Beispiel von einer Nachricht:
0x02 ist mein Sender (1 Byte lang)
0x0B ist die Länge ( also 11 Byte), Länge an sich ist auch ein Byte
0x01 ist mein Empfänger (1 Byte lang)
0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF sind meine
Nutzdaten (in diesem Fall 9 Byte von 32 möglichen)
0xB6 ist XOR-CRC (1 Byte)
Die Länge wird über Nutzdaten + Empfänger + XOR CRC ausgerechnet.
XOR wird über die gesamte Nachricht ausgerechnet.
Das Problem, was ich noch habe, dass ich die transfer.message nicht
dynamisch machen kann, da ich nicht weiss, wie lang der String sein
soll. Bzw. es ist von Fall zu Fall unterschiedlich. Deswegen muss ich
die Länge der Nutzdaten vor dem Bau der Nachricht schon wissen, was aber
kein Problem ist.
Grüsse
Heinrich
Moin Heinrich,
bitte durchdenk' mal die folgenden Fragen/Anmerkungen,
heute abend/nacht werde ich noch mal reinschauen,
jetzt muss ich erstmal weg.
- brauchst du build_ibus_message() dann gar nicht mehr?
oder soll der o.g. code das ersetzen?
- sizeof() und strlen() sind grundverschieden, bitte nachschlagen!
- Bei der Deklaration von transfer.message verwendest du 9 und nicht 32.
- Wenn es kein Problem ist, dass du die Länge der Nutzdaten vorher
kennst,
was ist dann dein Problem? Setz' die arraygröße von transfer.message
auf das maximum (32) und verwende die bekannte message-Größe als
parameter für memcpy().
- mit printf("%X", transfer.message[0]); gibst du nur das erste Zeichen
der Msg aus.
Ansonsten ist der Code doch brauchbar:
Vorschlag:
Hallo Daniel,
danke erstmal.
zum Punkt 1: Doch diese Funktion brauche ich nach wie vor. Ich mache mir
immer so kleine Programmchen, mit denen ich es dann austeste und diese
dann in das Programm einbaue. Also es wäre dann Ersatz.
zum Punkt 2: Stimmt, sizeof liefern die reservierte Grösse zurück und
strlen die Länge eines Strings. Hast Recht.
Zum Punkt 3: Ja, das habe ich testweise runtergesetzt. Es hat den
Hintergrund, dass nicht immer alle 32 Byte belegt werden, aber dann alle
32 Byte verschickt werden, wenn man die Grösse so belässt.
Zum Punkt 4: Ja, die Länge der Nachricht weiss ich schon vorher. Das
heisst, wenn ich zum Beispiel Nutzdaten als "92 95 83" habe, dann weiss
ich ja, dass diese Geschichte ja nur 3 Byte lang ist, dazu kommt noch 1
Byte für Empfänger und 1 Byte für CRC, ergibt also 5 Byte. Diese 5 Byte
kann ich dann schon mal reinschreiben als Länge.
Zum Punkt 5: Ja, das weiss ich, war testweise geändert.
Ich glaube, ich bohre einfach meine Sendenfunktion so weit auf, dass ich
diese Parameter an sie übergebe und sie dann die ganzen Daten
rausschickt und dann am Ende die XOR CRC ausrechnet. Ich denke, das wäre
das Einfachste.
Oder wie siehst Du das?
Danke & Grüsse
Heinrich
Ja, ich denke auch, dass deine Sendefunktion das ganz gut
komplett erledigen kann. So kompliziert ist es ja nicht mehr,
wenn du die erforderlichen Parameter ohnehin im Voraus kennst.
Gruß
Daniel
Ich wollte halt eine "generische" Funktion haben, die mir die
Nachrichten zusammenbaut. Aber das ist ja eigentlich nicht erforderlich,
da man sie beim Bauen ja auch gleich rauschicken kann.
Trotzdem vielen Dank.
Grüsse
Heinrich.