www.mikrocontroller.net

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


Autor: hobbytroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe eine Verständnisfrage zu Funktionspointern innerhalb eines 
structs.
Beipiel:
typedef struct sKanaleinstellungen
{
 uint_8 uPower;
 uint_8 uFreq;
 uint_8 uWav;
 (void*) pFunction;
 uint_8 uFunctionwert1;
 uint_8 uFunctionwert2;
 uint_8 uFunctionselect;
} tsKanaleinstellungen;

void Timer(uint_8 Wert1, uint_8 Wert2)
{
//mach irgendwas
}

void Zaehler(uint_8 Wert1, uint_8 Wert2, uint_8 Wert3)
{
//mach was anderes
}

void main(void)
{
 // Kanäle einrichten
 tsKanaleinstellungen Kanal1, Kanal2;

 // Funktionszuweisung
 Kanal1.pFunction = Timer;
 Kanal2.pFunction = Zaehler;

 // Funktionen ausführen
 Kanal1.pFunction(12, 44);
 Kanal2.pFunction(66, 129, 3);
}

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: hobbytroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK,
danke ;)
Hmm, jetzt mal 'ne doofe Frage ginge dann:
typedef struct sKanaleinstellungen
{
 uint_8 uPower;
 uint_8 uFreq;
 uint_8 uWav;
 (void*) pFunction(struct sKanaleinstellungen Param);
 uint_8 uFunctionwert1;
 uint_8 uFunctionwert2;
 uint_8 uFunctionselect;
} tsKanaleinstellungen;
Weil
typedef struct sKanaleinstellungen
{
 uint_8 uPower;
 uint_8 uFreq;
 uint_8 uWav;
 (void*) pFunction(tsKanaleinstellungen Param);
 uint_8 uFunctionwert1;
 uint_8 uFunctionwert2;
 uint_8 uFunctionselect;
} 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:
typedef struct sWerte
{
 uint_8 uFunctionwert1;
 uint_8 uFunctionwert2;
 uint_8 uFunctionselect;
} tsWerte;

typedef struct sKanaleinstellungen
{
 uint_8 uPower;
 uint_8 uFreq;
 uint_8 uWav;
 (void*) pFunction(tsWerte Werte);
 tsWerte Werte;
} tsKanaleinstellungen;

nehmen.
Oder hab' ich gerade wieder was verpeilt ?
Danke,
Hobbytroniker

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hobbytroniker wrote:
> Weil
>
> typedef struct sKanaleinstellungen
> {
>  uint_8 uPower;
>  uint_8 uFreq;
>  uint_8 uWav;
>  (void*) pFunction(tsKanaleinstellungen Param);
>  uint_8 uFunctionwert1;
>  uint_8 uFunctionwert2;
>  uint_8 uFunctionselect;
> } tsKanaleinstellungen;
> 
> 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
typedef struct sKanaleinstellungen tsKanaleinstellungen;

struct sKanaleinstellungen
{
 uint8_t uPower;
 uint8_t uFreq;
 uint8_t uWav;
 void (*pFunction) (tsKanaleinstellungen* Param);
 uint8_t uFunctionwert1;
 uint8_t uFunctionwert2;
 uint8_t uFunctionselect;
};

dann deine Lösung


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

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.