Funktionspointer

Gast #1051666
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
1
void func1(int id, char data);
2
void func2(int id, char *data);
3
void func3(int id, int32_t data);

aufnehemen können.

Geht sowas ?

Gruss karl
#1051671
Hallo,
nach folgendem Muster:
1
typedef void ( *TLCD_GOTO_XY ) ( int, int );
2
typedef void ( *TLCD_WRITE_TEXT ) ( char* pText );
3
typedef void ( *TLCD_VOID ) (void);
4

5
TLCD_GOTO_XY LCD_GOTO_XY;
6
TLCD_WRITE_TEXT LCD_WRITE_TEXT;

Gruß
Frank
Persönliche Seite #1051687
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
>
>
1
> void func1(int id, char data);
2
> void func2(int id, char *data);
3
> void func3(int id, int32_t data);
4
>
>
> aufnehemen können.
>
> Geht sowas ?

Jepp. Ein void* kann jede Art von Zeiger halten.
1
void * f1 = func1;
2
void * f2 = func2;
3
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:
1
typedef void (*func2_t) (int, char*);
2

3
// Funktion vom Prototyp wie func2 aufrufen
4
void dispatch (void * p)
5
{
6
   ((void(*)(int,char*)) p) (1, 'A');
7
   // alternativ
8
   ((func2_t) p)) (1, 'A');
9
}
10

11
void dispatch_func2_alike (func2_t f)
12
{
13
   f (1, 'A');
14
}
Gast #1051821
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.
Persönliche Seite #1051911
By the way: Es gibt hier auch andere Lösungen als über f-Pointer zu 
gehen, zB Verwendung von varargs.
1
#include <stdarg.h>
2

3
enum
4
{ 
5
    AS_STRING,
6
    AS_INT
7
};
8

9
void vfunc (int id, ...)
10
{
11
    va_list vlist;
12
    va_start (vlist, id);
13

14
    switch (id)
15
    {
16
         case AS_STRING:
17
         {
18
               char * p = va_arg (vlist, char*);
19
               break;
20
         }
21
         case AS_INT:
22
         {
23
               int i = va_arg (vlist, int);
24
               break;
25
         }
26
    }
27

28
    va_end (vlist);
29
}
30

31
void foo ()
32
{
33
    vfunc (AS_INT, 42);
34
    vfunc (AS_STRING, "Hallo Welt");
35
}

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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.