Forum: Compiler & IDEs Wie Funktionen mit Parametern als void pointer in struct ?


von hobbytroniker (Gast)


Lesenswert?

Hallo,
ich habe eine Verständnisfrage zu Funktionspointern innerhalb eines 
structs.
Beipiel:
1
typedef struct sKanaleinstellungen
2
{
3
 uint_8 uPower;
4
 uint_8 uFreq;
5
 uint_8 uWav;
6
 (void*) pFunction;
7
 uint_8 uFunctionwert1;
8
 uint_8 uFunctionwert2;
9
 uint_8 uFunctionselect;
10
} tsKanaleinstellungen;
11
12
void Timer(uint_8 Wert1, uint_8 Wert2)
13
{
14
//mach irgendwas
15
}
16
17
void Zaehler(uint_8 Wert1, uint_8 Wert2, uint_8 Wert3)
18
{
19
//mach was anderes
20
}
21
22
void main(void)
23
{
24
 // Kanäle einrichten
25
 tsKanaleinstellungen Kanal1, Kanal2;
26
27
 // Funktionszuweisung
28
 Kanal1.pFunction = Timer;
29
 Kanal2.pFunction = Zaehler;
30
31
 // Funktionen ausführen
32
 Kanal1.pFunction(12, 44);
33
 Kanal2.pFunction(66, 129, 3);
34
}
Würde das funktionieren, oder muß ich im struct festlegen, ob und 
wieviele Parameter die Funktion hat ?
Momentan bekomme ich den WinAVR irgendwie nicht zum laufen, aber ich 
möchte ja wissen wie es einwandfrei in C aussehen müßte ;)
Weil es wäre sehr schön und universell, wenn ich es so nehmen könnte.
Da C auch uneingeschränkte Parameterübergabe unterstützt habe ich mir 
das so gedacht.
Geht das oder bin ich komplett auf der falschen Schiene gelandet ?
Danke,
Hobbytroniker

von Karl H. (kbuchegg)


Lesenswert?

> Würde das funktionieren, oder muß ich im struct festlegen, ob und
> wieviele Parameter die Funktion hat ?

Nicht nur im struct.
Bei einem Funktionspointer musst du immer festlegen, wieviele
Parameter die Funktion hat und von welchem Typ sie sind.
Wie soll den der Compiler sonst kontrollieren, ob du beim
Aufruf auch die richtige Anzahl und den richtigen Typ übergeben
hast oder ob vielleicht ein paar Typanpassungen notwendig sind.

> Momentan bekomme ich den WinAVR irgendwie nicht zum laufen, aber ich
> möchte ja wissen wie es einwandfrei in C aussehen müßte ;)

http://www.mikrocontroller.net/articles/FAQ#Funktionszeiger

> Weil es wäre sehr schön und universell, wenn ich es so nehmen könnte.
> Da C auch uneingeschränkte Parameterübergabe unterstützt habe ich mir
> das so gedacht.

Oh. Glaub mir. Den Weg der 'variadischen Funktionen' willst du
nciht wirklich gehen. Das bringt mehr Probleme als es dir nützt.

Mach dir für die Argumente an eine Funktion eine schöne Datenstruktur,
vielleicht ein Array, und übergib an alle Funktionen immer die
gleiche Anzahl an Parametern. In dem Fall: Anzahl Arrayelemente
und Array.

Im schlimmsten Fall verpasst du der Funktion Timer da oben
ein drittes Argument, dass in der Funktion nicht benutzt wird.
Das ist pragmatisch gesehen die einfachste Lösung, und dürfte auch
vom Laufzeitverhalten her nicht so schlecht abschneiden.

von hobbytroniker (Gast)


Lesenswert?

OK,
danke ;)
Hmm, jetzt mal 'ne doofe Frage ginge dann:
1
typedef struct sKanaleinstellungen
2
{
3
 uint_8 uPower;
4
 uint_8 uFreq;
5
 uint_8 uWav;
6
 (void*) pFunction(struct sKanaleinstellungen Param);
7
 uint_8 uFunctionwert1;
8
 uint_8 uFunctionwert2;
9
 uint_8 uFunctionselect;
10
} tsKanaleinstellungen;
Weil
1
typedef struct sKanaleinstellungen
2
{
3
 uint_8 uPower;
4
 uint_8 uFreq;
5
 uint_8 uWav;
6
 (void*) pFunction(tsKanaleinstellungen Param);
7
 uint_8 uFunctionwert1;
8
 uint_8 uFunctionwert2;
9
 uint_8 uFunctionselect;
10
} tsKanaleinstellungen;
ist dem Compiler ja an der Stelle nicht bekannt ?
Das wäre eine für mich Ideale Lösung.
Oder als Notlösung müßte ich dann wohl:
1
typedef struct sWerte
2
{
3
 uint_8 uFunctionwert1;
4
 uint_8 uFunctionwert2;
5
 uint_8 uFunctionselect;
6
} tsWerte;
7
8
typedef struct sKanaleinstellungen
9
{
10
 uint_8 uPower;
11
 uint_8 uFreq;
12
 uint_8 uWav;
13
 (void*) pFunction(tsWerte Werte);
14
 tsWerte Werte;
15
} tsKanaleinstellungen;
nehmen.
Oder hab' ich gerade wieder was verpeilt ?
Danke,
Hobbytroniker

von Karl H. (kbuchegg)


Lesenswert?

hobbytroniker wrote:
> Weil
>
1
> typedef struct sKanaleinstellungen
2
> {
3
>  uint_8 uPower;
4
>  uint_8 uFreq;
5
>  uint_8 uWav;
6
>  (void*) pFunction(tsKanaleinstellungen Param);
7
>  uint_8 uFunctionwert1;
8
>  uint_8 uFunctionwert2;
9
>  uint_8 uFunctionselect;
10
> } tsKanaleinstellungen;
11
>
> ist dem Compiler ja an der Stelle nicht bekannt ?

Niemand sagt, dass du die struct im typedef
definieren musst. Wenn du dann noch die Funktionspointer-
Syntax richtig stellst, ist
1
typedef struct sKanaleinstellungen tsKanaleinstellungen;
2
3
struct sKanaleinstellungen
4
{
5
 uint8_t uPower;
6
 uint8_t uFreq;
7
 uint8_t uWav;
8
 void (*pFunction) (tsKanaleinstellungen* Param);
9
 uint8_t uFunctionwert1;
10
 uint8_t uFunctionwert2;
11
 uint8_t uFunctionselect;
12
};

dann deine Lösung


(Ach ja: Ich denke mal, du willst einen Pointer auf
die Struktur übergeben und nicht eine Struktur selbst)

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.