"Metaprogrammierung" (und Funktionszeiger)
-
Hi!
ich habe eine textdatei in der pseudo-funktionsaufrufe stehen - zb. steht in der textdatei l20, das soll dann dazu führen dass das programm l(20) ausführt...
einen parser (und den rest rundherum) dafür hab ich erstellt und es funktioniert auch wunderbar, aber es sieht derzeit so aus, dass ich die datei zeile für zeile einlese (fgets) und dann bei jeder zeile einzeln entscheide welche funktion aufgerufen wird, diesen aufruf mache und dann die nächste zeile lese usw.
nach möglichkeit würde ich aber die aufrufe gerne "vorbereiten" damit zw. den aufrufen selbst möglichst wenig zeit vergeht (vor beginn und nach ablauf der abarbeitung aller aufrufe darfs gerne etwas länger dauern) - auf der suche nach möglichkeiten hierfür ist mir dann eingefallen dass es in c funktionszeiger gibt, also habe ich ein wenig herumgesucht auf google und folgendes gefunden:
http://www.newty.de/fpt/fpt.html
die idee mit dem array ist ja schon sehr gut, ich könnte die datei ja einfach in ein array mit funktionszeigern "umparsen" und dann mit einer schleife eine funktion nach der anderen aufrufen - wenn da die parameter nicht wären...
deswegen meine Frage: kann man funktionszeiger mit "fixen" parametern erstellen? also dass ich z.b. folgendes mache:
...
//beim parsen der datei
instruktion[i] = &l(20);
...so dass dann
...
//bein ausführen
instruktion[i];
...die entsprechende funktion aufruft
kann ich soetwas in c überhaupt realisieren? bzw. gibt es etwas vergleichbares?
wie sieht es aus wenn die funktionen als inline definiert sind?
bringt es von der performance her etwas oder war mein ansatz die anwendung auf diese art zu optimieren ein irrweg? bzw. gibt es vorschläge wie ich es besser machen könnte?weiteres dann noch eine allgemein frage zu funktionszeigern, brauch ich diese eigenartige syntax (*pt2Function)(2, 4) oder reicht evtl. auch *pt2Function(2, 4)
danke!
-
Timmy schrieb:
...
//beim parsen der datei
instruktion[i] = &l(20);
...so dass dann
...
//bein ausführen
instruktion[i];
...
die entsprechende funktion aufruftman kann sich z.b. arrays aus function pointern anlegen:
// 3 funktionen void f1(){puts("f1");} void f2(){puts("f2");} void f3(){puts("f3");} // array mit function pointern void (*fp[])() = {f1, f2, f3};
und dann so aufrufen:
fp[0](); // gibt f1 aus fp[1](); // gibt f2 aus fp[2](); // usw...
-
Haben alle von Deinem Parser aufzurufende Funktionen die selbe Signatur?
greetz, Swordfish
-
Vielleicht ein anderer Vorschlag:
Definier' dir Structs, die die Funktion mit ihren Argumenten speichern
und speicher' diese in einem Array.typedef struct { int key; } func_t; struct func1 { int key; void (*func)(int); int arg; } struct func2 { int key; void (*func)(int, int); int arg1, arg2; }
Der Key gibt an, um welchen Typ von Struct es sich handelt.
Angenommen: struct func1 hat den key 1 und struct func2 den key 2.
und weiterhin hast du ein Array vom Typ func_t ** arr definiert.Dann kannst du mit:
switch(arr[i]->key) { case 1: { struct func1* f1 = (struct func1*) arr[i]; f1->func(f1->arg); } break; case 2: { struct func2* f2 = (struct func2*) arr[i]; f2->func(f2->arg1, f2->arg2); } break; }
auf die einzelnen Elemente zugreifen und ausführen.
Hierbei ist wichtig, dass key immer an erster Stelle im Struct steht.
Gruß mcr
PS: und hier mal ein komplettes Beispiel:
#include <stdio.h> #include <stdlib.h> typedef struct { int key; } func_t; struct func1 { int key; void (*func)(int); int arg; }; struct func2 { int key; void (*func)(int, int); int arg1, arg2; }; void func1(int a) { printf("1: a=%d\n", a); } void func2(int a, int b) { printf("2: a=%d b=%d\n", a, b); } void call_func(func_t *a) { switch(a->key) { case 1: { struct func1* f1 = (struct func1*) a; f1->func(f1->arg); } break; case 2: { struct func2* f2 = (struct func2*) a; f2->func(f2->arg1, f2->arg2); } break; default: printf("(E): invalid key: %d\n", a->key); } } int main (void) { func_t *arr[3]; struct func1 *a; struct func2 *b; a = malloc(sizeof*a); a->key = 1; a->func = func1; a->arg = 10; arr[0] = (func_t*)a; b = malloc(sizeof*b); b->key = 2; b->func = func2; b->arg1 = 1; b->arg2 = 2; arr[1] = (func_t*) b; a = malloc(sizeof*a); a->key = 1; a->func = func1; a->arg = 20; arr[2] = (func_t*) a; call_func(arr[0]); call_func(arr[1]); call_func(arr[2]); return 0; }
-
ich werd das versuchen
danke!