Datentyp für eine Funktion
-
Ich hatte mir vor kurzem eine Funktion geschrieben, der man einen Zeiger auf eine Funktion übergeben konnte, die dann aufgerufen wurde (callback). Hat auch wunderbar funktioniert, da ich als Funktionsparameter den Typ DLGPROC aus der WINAPI geklaut habe. Allerdings ist das so ein Bisschen auf "Quick and Dirty" gemachtund deshalb frage ich mal hier, was man als Datentyp für eine Funktion nehmen kann. Ich habe es schon mit (_stdcall*) versucht, da meckert mein Compiler allerdings...
-
void foo(void);
sieht so ausvoid (*p)(void)
mach doch einfach:
char* p=foo;und schon sagt er
void (*foo)(void) kann nicht in char* konvertiert werden
-
Das habe ich jetzt nicht so ganz verstanden... Besonders die letzte Zeile deines Beitrags irritiert mich
Ich poste hier mal mein altes Programm, vielleicht wird dann klarer, was ich meine:#include "windows.h" #include <stdio.h> int _stdcall PrintAnotherShit(DWORD x, DWORD y); void SetRecall(DLGPROC* AProc, DWORD x, DWORD y); void NotMessage(); int main(int argc, char* argv[]) { printf("Hello world!\n"); SetRecall((DLGPROC*)PrintAnotherShit, 200, 400); return 0; } int __stdcall PrintAnotherShit(DWORD x, DWORD y) { DWORD db; DWORD k; __asm{ mov eax, [ebp+12] mov k, eax mov db, 0xFFF0 mov eax, db xor eax, eax jz iszero jmp end iszero: call NotMessage end: } printf("db ist %d\n", db); printf("x ist %d\n", x); printf("y ist %d\n", y); printf("y ist %d\n", k); return x*y; } void SetRecall(DLGPROC* AProc, DWORD x, DWORD y) { DWORD dw; __asm { push y push x call AProc mov dw, eax } printf("PrintAnotherShit() gibt %d zurueck\n", dw); } void NotMessage() { printf("xor db, db ist 0!\n"); }
[ Dieser Beitrag wurde am 22.03.2003 um 19:24 Uhr von hackbert editiert. ]
-
Was willst du jetzt dazu wissen?
-
Ich will wissen, wodurch ich DLGPROC ersetzen muss, damit ich nicht DLGPROC gebrauchen muss, da diese ja in den windows headern drinne ist und die nicht includet werden sollen.
-
DLGPROC sieht so aus. kannst du ja wohl ganz leicht auf deine funktion ändern
typedef INT_PTR (CALLBACK* DLGPROC)(HWND, UINT, WPARAM, LPARAM);
-
void SetRecall(int (*foo)(DWORD,DWORD), DWORD x, DWORD y) { int dw = foo(x,y) }
das _stdcall ist kein ANSI-C, keine Ahnung wo das hinmuß. Versuchsweise würd ichs nach int oder vor foo setzen Guck dir doch im Zweifelsfall die Deklaration in der windows.h an.
Damit sollten sich die 2 stinkenden Stellen (cast nach DLGPROC und Calling Convention von Hand) ausmerzen lassen. OT/BTW war nicht stdcall so, dass die Argumente von links nach rechts auf den Stack wandern?
-
__stdcall muss dahin wo CALLBACK steht. aber CALLBACK ist schon __stdcall
-
Original erstellt von <??>:
**DLGPROC sieht so aus. kannst du ja wohl ganz leicht auf deine funktion änderntypedef INT_PTR (CALLBACK* DLGPROC)(HWND, UINT, WPARAM, LPARAM);**
hä? Das ist die definition von INT_PTR...
-
Original erstellt von Bashar:
**
Damit sollten sich die 2 stinkenden Stellen (cast nach DLGPROC und Calling Convention von Hand) ausmerzen lassen.
**Die Calling Convention von Hand sollte drinne bleiben, die war zu Lernzwecken drin.
Original erstellt von Bashar:
**
OT/BTW war nicht stdcall so, dass die Argumente von links nach rechts auf den Stack wandern?**Ja. Wenn dich sowas interessiert, dann schau dir mal das hier an: http://bkausbk.netfirms.com/callconv.html#STDCALL
Man kann auch das ganze mit long machen:
void SetRecall(long AProc, DWORD x, DWORD y) { DWORD dw; __asm { push y push x call AProc mov dw, eax } printf("PrintAnotherShit() gibt %d zurueck\n", dw); }
[ Dieser Beitrag wurde am 22.03.2003 um 20:47 Uhr von hackbert editiert. ]
-
hä? Das ist die definition von INT_PTR...
quatsch :o
-
jo, hab mich geirrt! Sorry. Hatte das andersherum gedacht, wenn du weißt was ich meine...
-
wenn du weißt was ich meine...
ja
-
hackbert: Öhm ... und warum packst du sie dann von rechts nach links drauf?
-
In dem Text steht doch
Die Parameter werden auch von rechts nach links auf den Stack kopiert wie bei cdecl.
Dann wäre das doch richtig, was er gemacht hat?
-
Hab mich verlesen. Die Parameter werden von rechts nach links auf den Stack gelegt, also der letzte Parameter zuerst und der erste zuletzt.