Hallo!
Ich programmiere gerade eine Firmware in C für einen MSP430 unter Code
Composer Studio v4 von Ti.
In meinem Programm bekommt eine Funktion u.a. einen byte-Pointer, der
auf ein entsprechendes Array zeigt, übergeben.
In diesem Array stehen serialisierte Daten, die meine Funktion
entsprechend wieder auspacken muss. Das klappt soweit ganz gut, nur bei
Funktionspointern hapert es.
Egal, wie ich es drehe und wende bekomme ich immer irgendwelche
Kompiler-Warnungen und/oder -Fehler.
Wie kann ich einen byte-Pointer in einen Funktionspointer casten?
Danke für Eure Hilfe!
Gruß
Mirco
P.S.:
byte = typedef unsigned char
P.P.S.:
Pseudocode:
1
voidMeineFunktion(FrameIDwert)
2
{
3
...
4
}
Beispiel: &MeineFunktion = 0x1234
1
bytearray[2];
2
array[0]=MSBAddresseaufFunktion;hier:0x12
3
array[1]=LSBAddresseaufFunktion;hier:0x34
4
byte*datapointer=&array[0];
Funktionspointer zeigt auf "void (*Callback) (FrameID wert)"
Gesucht ist also:
Mirco schrieb:> Egal, wie ich es drehe und wende bekomme ich immer irgendwelche> Kompiler-Warnungen und/oder -Fehler.
"irgendwelche"? Keine ganz konkreten, die du posten könntest?
> Wie kann ich einen byte-Pointer in einen Funktionspointer casten?
So wie du es mit jedem anderen Typ auch tun würdest, indem du den
Zieltyp in Klammern davor schreibst. Zur besseren Lesbarkeit bietet sich
ein typedef an.
> Funktionspointer zeigt auf "void (*Callback) (FrameID wert)"> Gesucht ist also:> void (*Callback) (FrameID wert);> Callback = *datapointer> Ziel: Callback = 0x1234
Hallo!
Vielen Dank für die schnellen Antworten.
Rolf Magnus schrieb:> "irgendwelche"? Keine ganz konkreten, die du posten könntest?
"void *" is incompatible with parameter of type "void (*)(FrameID)"
und
"nonstandard conversion between pointer to function and pointer to data"
zum Beispiel.
Letzteres ist mein Hauptproblem (die anderen resultieren auf den
kläglichen Verscuehn, den Pointer richtig zu casten) und kommt auch bei
der Verwendung von typedef, wie es von euch vorgeschlagen wurde.
Gruß
Mirco
Mirco schrieb:> "void *" is incompatible with parameter of type "void (*)(FrameID)"> und "nonstandard conversion between pointer to function and pointer to> data" zum Beispiel.
Ah, ok. Dann hast du wahrscheinlich den ANSI- bzw. ISO-Modus
eingestellt. In ISO-C sind Konvertierungen zwischen Datenzeigern und
Funktionszeigern generell verboten.
So vielleicht?
Dieses Beispiel kompiliert einwandfrei, allerdings geht es zur Laufzeit
in die Hose, weil an Adresse 0x1234 halt irgendwas liegen kann. Wenn man
die auskommentierte Zeile mit kompiliert, läuft's.
1
#include<stdio.h>
2
typedefunsignedcharbyte;
3
typedefunsignedintFrameID;
4
typedefvoid(*Callback_t)(FrameID);
5
6
voidmeineFunktion(FrameIDwert)
7
{
8
printf("FrameID: %d\n",wert);
9
}
10
11
intmain()
12
{
13
bytezahl=4;
14
15
bytearray[2];
16
array[0]=0x12;//MSB
17
array[1]=0x34;//LSB
18
byte*datapointer;
19
datapointer=(byte*)(array[0]<<8)+array[1];
20
21
printf("datapointer hat den Wert: %p\n",datapointer);
Eventuell könnte man den Compiler mit einer union austricksen.
Allerdings: Wenn sich der Compiler standhaft weigert einen Datenpointer
zu einem Funktionspointer umzucasten, dann denke ich mal, wird das
seinen Grund haben (inkompatible Länge von Pointern)
Karl heinz Buchegger schrieb:> wird das seinen Grund haben (inkompatible Länge von Pointern)
Ähm, wie genau dies? Zeigervariablen an sich haben doch immer die
gleiche Länge bzw. Größe? Oder ist damit gemeint dass der Adressraum für
verschiedene Speicherbereiche unterschiedlich groß sein kann, z.B. auf
einem Prozessor mit Harvard-Architektur?
Mark Brandis schrieb:> Karl heinz Buchegger schrieb:>> wird das seinen Grund haben (inkompatible Länge von Pointern)>> Ähm, wie genau dies? Zeigervariablen an sich haben doch immer die> gleiche Länge bzw. Größe?
No.
Dafür gibt es keine Garantie.
Ein void* kann alle Datenzeiger aufnehmen. Aber kein Mensch sagt, dass
Funktionszeiger dieselbe Länge haben müssen. Auch nicht der C-Standard.
> Oder ist damit gemeint dass der Adressraum für> verschiedene Speicherbereiche unterschiedlich groß sein kann, z.B. auf> einem Prozessor mit Harvard-Architektur?
Harvard ist schon ein gutes Stichwort.
Wenn dein µC nur 256 Bytes SRAM hat, dann genügt es, wenn man einen
Datenpointer (einen int* oder einen char* oder ...) nur 1 Byte groß
macht. Wenn er aber zb 1K für Programmcode (zb in einem Flash) hat, dann
reicht für Funktionspointer ein einzelnes lausiges Byte klarerweise
nicht aus.
Wie das jetzt bei diesem Compiler und beim MSP ist, weiß ich nicht.
Normalerweise weigern sich Compiler spätestens nach einem Cast nicht
mehr. Wenn dieser Compiler es trotzdem tut, könnte es einen Grund dafür
geben.
Hallo!
Mein Problem ist nicht das:
Mark Brandis schrieb:> datapointer = (byte*)(array[0] << 8) + array[1];
Sondern das:
Mark Brandis schrieb:> Callback = (Callback_t)datapointer;Karl heinz Buchegger schrieb:> enn dein µC nur 256 Bytes SRAM hat, dann genügt es, wenn man einen> Datenpointer (einen int* oder einen char* oder ...) nur 1 Byte groß> macht. Wenn er aber zb 1K für Programmcode (zb in einem Flash) hat, dann> reicht für Funktionspointer ein einzelnes lausiges Byte klarerweise> nicht aus.>>> Wie das jetzt bei diesem Compiler und beim MSP ist, weiß ich nicht.> Normalerweise weigern sich Compiler spätestens nach einem Cast nicht> mehr. Wenn dieser Compiler es trotzdem tut, könnte es einen Grund dafür> geben.>
Ich glaube über 256 Byte RAM und 1kByte Programmcode brauchen wir nicht
reden. Wir reden hier von mehreren kByte. ;)
Habe mal mit sizeof die Größe von zwei drei Pointern überprüft. Alle
waren 2 Byte groß.
Mirco schrieb:> Als bei mir noch "void(*)(FrameID)" satt "Callback_t" stand, hat der> Compiler es nicht akzeptiert...
Grrrrrrr
Zitat
> Letzteres ist mein Hauptproblem (die anderen resultieren auf den> kläglichen Verscuehn, den Pointer richtig zu casten) und kommt auch bei> der Verwendung von typedef, wie es von euch vorgeschlagen wurde.
Es hat schon seinen Grund, warum ich dir als erstes einen typedef für
den Funktionspointer vorgeschlagen habe. Man verhaut sich leicht mit der
Syntax, wenn man jedesmal Funktionspointer-Datentypen komplett
ausschreiben muss.
Hab doch deinen Ratschlag zu Herzen genommen und umgesetzt. Nur wurde in
dem von euch geschriebenen Beispielcode der Datenpointer direkt in die
Callback-Funktion gecastet und nicht als Pointer, was jetzt entgültig
die Lösung war ...