mikrocontroller.net

Forum: Compiler & IDEs Funktionspointer


Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo eine Frage,

Wie kann ich in C ein Funktionpointer definieren der verschieden 
Funktionen aufnehemen kann. Ich möchte sowas machen:

Einfunktionpointer soll Funktionen der Art
void func1(int id, char data);
void func2(int id, char *data);
void func3(int id, int32_t data);

aufnehemen können.

Geht sowas ?

Gruss karl

Autor: Frank Link (franklink)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
nach folgendem Muster:
typedef void ( *TLCD_GOTO_XY ) ( int, int );
typedef void ( *TLCD_WRITE_TEXT ) ( char* pText );
typedef void ( *TLCD_VOID ) (void);

TLCD_GOTO_XY LCD_GOTO_XY;
TLCD_WRITE_TEXT LCD_WRITE_TEXT;

Gruß
Frank

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja ja aber ich brauache einer der alle drei kann.
Ich wollte es mit:

void (*funcPTR)(int,void*);

machen geht das ?

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja void kannst ja beliebig casten.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gast wrote:
> Hallo eine Frage,
>
> Wie kann ich in C ein Funktionpointer definieren der verschieden
> Funktionen aufnehemen kann. Ich möchte sowas machen:
>
> Einfunktionpointer soll Funktionen der Art
>
>
> void func1(int id, char data);
> void func2(int id, char *data);
> void func3(int id, int32_t data);
> 
>
> aufnehemen können.
>
> Geht sowas ?

Jepp. Ein void* kann jede Art von Zeiger halten.
void * f1 = func1;
void * f2 = func2;
void * f3 = func3;

Allerdings musst du den void* wieder auf den richtigen Typ casten, weil 
ja all deine Funktionen unterschiedlichen Prototyp haben.
Je nach Aufrufkonvention des Compilers crasht das sonst:
typedef void (*func2_t) (int, char*);

// Funktion vom Prototyp wie func2 aufrufen
void dispatch (void * p)
{
   ((void(*)(int,char*)) p) (1, 'A');
   // alternativ
   ((func2_t) p)) (1, 'A');
}

void dispatch_func2_alike (func2_t f)
{
   f (1, 'A');
}

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anstelle des void-Pointers könntest du auch eine Union verwenden, die
für jeden der drei Funktionstypen einen Eintrag enthält. Du ersparst dir
dadurch die Casterei und machst deinen Code etwas typsicherer.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
By the way: Es gibt hier auch andere Lösungen als über f-Pointer zu 
gehen, zB Verwendung von varargs.
#include <stdarg.h>

enum
{ 
    AS_STRING,
    AS_INT
};

void vfunc (int id, ...)
{
    va_list vlist;
    va_start (vlist, id);

    switch (id)
    {
         case AS_STRING:
         {
               char * p = va_arg (vlist, char*);
               break;
         }
         case AS_INT:
         {
               int i = va_arg (vlist, int);
               break;
         }
    }

    va_end (vlist);
}

void foo ()
{
    vfunc (AS_INT, 42);
    vfunc (AS_STRING, "Hallo Welt");
}

Aber wie auch immer: irgendwo muss gemerkt werden,
wie die Daten // ein f-Pointer // eine Union zu interpretieren ist.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.