Funktionspointer

Gast #1051666
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
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
Persönliche Seite #1051687
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
>
>
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
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.
Persönliche Seite #1051911
Lesenswert?

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

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