CCE: Casten eines Funktionspointers von einem Byte-Pointer

Gast #2041793
Lesenswert?

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
void MeineFunktion(FrameID wert)
2
{
3
...
4
}
Beispiel: &MeineFunktion = 0x1234
1
byte array[2];
2
array[0] = MSB Addresse auf Funktion; hier: 0x12
3
array[1] = LSB Addresse auf Funktion; hier: 0x34
4
byte* datapointer = &array[0];

Funktionspointer zeigt auf "void (*Callback) (FrameID wert)"
Gesucht ist also:
1
void (*Callback) (FrameID wert);
2
Callback = *datapointer
Ziel: Callback = 0x1234
Gast #2041833
Lesenswert?

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
1
typedef void(*Callback_t)(FrameID);
2

3
Callback_t Callback;
4

5
Callback = (Callback_t)datapointer;
Gast #2041846
Lesenswert?

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
Gast #2041894
Lesenswert?

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.
#2042079
Lesenswert?

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
typedef unsigned char byte;
3
typedef unsigned int  FrameID;
4
typedef void(*Callback_t)(FrameID);
5

6
void meineFunktion(FrameID wert)
7
{
8
  printf("FrameID: %d\n", wert);
9
}
10

11
int main()
12
{
13
  byte zahl = 4;
14

15
  byte array[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);
22

23
  Callback_t Callback;
24
  Callback = (Callback_t)datapointer;
25
  
26
  printf("Callback hat den Wert:    %p\n", Callback);
27
  //Callback = &meineFunktion;
28

29
  (*Callback)(zahl);
30

31
  return 0;
32
}
#2042419
Lesenswert?

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.
Gast #2042686
Lesenswert?

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ß.
Gast #2042700
Lesenswert?

HAB'S!

Diese Lösugn habe ich zwar vorher auch schon probiert, dieses mal habe 
ich aber die typedef-Definition verwendet:
1
Callback_t* pCallback;
2
pCallback = (Callback_t*)datapointer;
lautet die Lösung.

Als bei mir noch "void(*)(FrameID)" satt "Callback_t" stand, hat der 
Compiler es nicht akzeptiert...

Danke euch allen!

Gruß
Mirco
#2043154
Lesenswert?

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.
Gast #2043234
Lesenswert?

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 ...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren