void pointer in funktion umcasten
-
Hallo an alle,
Ich möchte eine art Wrapper für Threads schreiben, übergebe dafür die Funktionsadresse als void Pointer und möchte dann diesen aufrufen.
int f1(int a, int b){ /* do something */ return 0;} void caller(int a, int b, void *function){ printf("%d", function(a, b)); } int main(){ caller(4, 5, f1); return 0; }
Dieser Code scheitert in Zeile 4, da ein Voidpointer nunmal nicht aufrufbar ist. Also muss ich ihn auf Typ Funktion umcasten.
Ich habe ein bischen recherchiert und verschiedene Versionen gefunden, von((int)(*)(int, int))function(a, b);
bis
typedef int(*func)(int, int); ... ((func) function)(a,b);
in den verschiedensten Varianten. Nichts davon wird vom gcc 3.4.5 (mingw) akzeptiert.
Wie ist so ein Cast möglich? Eine Möglichkeit muss es geben, Quicksort mit Vergleichsfunktion kanns ja auch.
Vielen Dank für die Hilfe im Vorraus.
-
etwa so:
int f1 (int a, int b) { return a*b; } int caller (int a, int b, void *f) { return ((int(*)(int,int))f)(a,b); } int main() { printf ("3 * 4 = %d\n", caller(3,4, f1)); }
^^fiese klammerei, sieht fast aus wie 'lisp'. mach's besser mit einem typedef
-
Boah cool funktioniert, danke
-
wär's nicht einfacher und eindeutiger so?
void caller(int a, int b, int (*function)(int,int)){ printf("%d", function(a, b)); }
dann sieht man sofort, dass 'function' eine Funktion und nicht einen beliebigen Zeiger erwartet.
-
^^vielleicht will er ja sowas wie eine 'high order function' basteln, die mit verschiedenen funktionen umgehen kann. aber das geht bestimmt noch besser als mit 'nem void*
-
Eigentlich will ich die Funktion
thread(int n, void *f, ...); //n=Anzahl der Argumente, f=Funktionspointer, ...=Parameter von f
implementieren, sie soll einen Thread starten, aus Portabilitätsgründen. Das mit den int's war nur ein Minimalbeispiel für das Castproblem, die Threadfunktion muss mit jeder denkbaren Funktion klarkommen, aber das funktioniert jetzt dank ;fricky ;D.
Ich weiß, dass mir alles um die Ohren fliegt, sobald ein Argument größer als ein Voidpointer ist. Bin noch nicht sicher ob irgendwas schlimmes passiert, wenn man eine void Funktion zu einer void *Funktion umdeklariert und dann mit dem erhaltenen (?) void pointer nichts tut. Offiziell ist es undefiniert.
Im Moment weigert sich CreateThread meinen Voidpointer als Funktion anzuerkennen, auch nach dem casten nicht.
error: invalid conversion from `DWORD ()(void)' to `DWORD ()(void)'
Scheint aber nur eine schlechte Fehlermeldung zu sein, der eigentliche Fehler ist irgendwo anders. Wahrscheinlich ist DWORD doppelt definiert oder so.Das ganze soll übrigens irgendwann mal ein Editor mit Semantikhighlighting werden. Dasselbe wie Syntaxhighlighting, nur dass auch Variablen entsprechend ihres Typs eingefärbt werden. Das hätte dann den Vorteil, dass man auf einen Blick sieht welchen Datentyp eine Variable hat oder eine Funktion zurückgibt/erhält und dass man Strukts die Elemente ansieht, ohne eine API zu wälzen, so Eclipse-mäßig. Wenn es fertig wird poste ich nen Link oder so.
MFG.
-
Ok, der Fehler hat sich auch erledigt, Windoof verlangt, dass die übergebene Funktion eine __stdcall-Funktion ist und man sollte _beginthreadex und nicht CreateThread benutzen.
Er kompiliert es jetzt zum ersten mal Fehlerfrei
-
;fricky schrieb:
etwa so:
int f1 (int a, int b) { return a*b; } int caller (int a, int b, void *f) { return ((int(*)(int,int))f)(a,b); } int main() { printf ("3 * 4 = %d\n", caller(3,4, f1)); }
^^fiese klammerei, sieht fast aus wie 'lisp'. mach's besser mit einem typedef
Vielleicht solltest du die Leute warnen, anstatt die Benutzung von undefined behaviour zu zeigen: http://www.safercode.com/blog/2008/11/25/generic-function-pointers-in-c-and-void.html
Felix