Forum: Compiler & IDEs Zeiger auf Funktion


von Mike (Gast)


Lesenswert?

Moin,

ich versuche mich gerade darin, einen Parser für RS232-Kommandos zu
schreiben. Leider habei ch ein paar Porbleme ein Kommando mit einer
Funktion zu verknüpfen.

Ich habe ein Array, in dem der Kommandstring und die dazu gehörigen
Funktion stehen sollen.
1
   typedef struct{
2
      char             CmdString[12];
3
      unsigned char    (*ExecuteFunction)(char * Data);
4
   }RemoteCommandStruct;

Das Problem ist, das die ExecuteFunktion das falsche Datenformat hat.
Weiß jemand welchen DatenTyp ich beim GCC nehmen muß, damit er sich
nicht "beklagt"?

MfG Mike

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Das Problem ist, das die ExecuteFunktion das
> falsche Datenformat hat.

Was hat sie?

Am besten, du postest mal die exakte Fehlermeldung mit (möglichst
in Englisch).

Die Deklararation sieht erstmal OK aus, aber die deklariert ja
nur einen Datentyp.  Den musst du noch irgendwo benutzen, und
dann musst du ja auch noch Funktionen haben, deren Adressen du
zum Initialisieren der Zeiger nehmen kannst.  Das braucht man
schon alles zusammen, um zu sehen, wo dein Problem liegt -- im
Moment ist schlicht kein Problem erkennbar.

von Mike (Gast)


Lesenswert?

Also, ich fülle die Tabelle wie folgt:
1
   {{"",     SCI_process_prompt},
2
    Die Tabelle geht hier noch weiter..

Wobei SCR_process_prompt der Name eine Funktion ist:
1
unsigned int SCI_process_prompt               (char * data)
2
{
3
//irgnedwas
4
}

Die Fehlermeldung ist dann

../parser.c:11: warning: initialization from incompatible pointer type


Auf einem anderen Controller mit anderem Compiler funktioniert das
ganze auch, nur leider mit dem GCC nicht.

von Mike (Gast)


Lesenswert?

Ach ja, der aufruf erfolgt später mit
1
(*RemCmdTbl[i].ExecuteFunction)(Data);

von Rolf Magnus (Gast)


Lesenswert?

Der Compiler hat ja auch recht. Du hast einen Zeiger auf eine Funktion,
die einen unsigned char zurückgibt, und willst ihn auf eine Funktion
zeigen lassen, die stattdessen einen unsigned int zurückgibt. Die Typen
müssen übereinstimmen.
Übrigens: Beim Aufruf kannst du die Dereferenzierung weglassen. Es
reicht also:
1
RemCmdTbl[i].ExecuteFunction(Data);

von Mike (Gast)


Lesenswert?

Ok, danke jetzt funktioniert es wieder so, wie es soll.

Das kommt davon, wenn man versucht aus 2 Programmen eins zu machen und
nicht auf Rückgabewerte achtet.

von Wolfram (Gast)


Lesenswert?

Es wäre besser die Adresse der Funktion zu speichern und eine Funktion
zu verwenden die einen char zurückgibt, wie in der Deklaration
angegeben.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Es wäre besser die Adresse der Funktion zu speichern

Huh?  Genau das tut er doch?!

Btw., ich würde keine Strings mit in das Array nehmen, sondern
stattdessen Zeiger auf Strings im Flash (PGM_P).

von Mike (Gast)


Lesenswert?

Den Rückgabewert der Funktion habe ich gerade auf char geändert. Ein Int
ist da echt übertrieben. Wobei der voherige Controller 16Bit hatte, da
war es egal.

Das mit den Strings im Flash klingt Interressant. Aber bis jetzt sollte
erstmal die Funktion selber laufen, dann wird weiter optimiert :-)

Beim optimieren bi nich übrigens auf noch ein Problem gestoßen:
Ich habe eine Tabelle mit den Fehlermeldungen, die bisher auch noch im
Ram liegt, allerdings wieß ich nciht, wie ich die in den Flash legen
kann.
1
   char  * Fault[4]   = {"OK",                                    // 0
2
                         "Bad command!",                             
3
  // 1
4
                         "Bad data format!",                   // 2
5
                         "Range error!",                       // 3
6
                        };

von Εrnst B. (ernst)


Lesenswert?

Für das Array mit char* im Flash gibts hier ein Beispiel:

http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_rom_array

/Ernst

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wobei ich die Notwendigkeit, auch die Zeiger in den ROM zu packen,
nicht immer sehe.   Die nehmen -- verglichen mit den vielen
Strings -- relativ wenig Platz ein.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.