Here is output:
g++ -DDEBUG -DUNITTEST -IC:/Users/Steven/Dropbox/Programming/entropy_p5_makefile/cpp/game/../include/ -O0 -g3 -Wall -c -fmessage-length=0 -o Input.o ..\Input.cpp
..\Input.cpp: In function 'void mousehookCustomRoutine(E_thread*, void*)':
..\Input.cpp:78:93: error: invalid conversion from 'LRESULT (*)(int, WPARAM, LPARAM)' to 'LRESULT (*)(int, WPARAM, LPARAM)'
..\Input.cpp:78:93: error: initializing argument 2 of 'void* SetWindowsHookExA(int, LRESULT (*)(int, WPARAM, LPARAM), HINSTANCE__*, DWORD)'
Build error occurred, build is stopped
This is the code:
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
//...
}
void mousehookCustomRoutine(E_thread *me, void *arg = (void *)&MouseHookProc) {
// arg is the ptr to LL Mouse Routine
me->sendMessage(0x14,me,(void*)GetCurrentThreadId());
// send message to self in order for my parent to know how to identify me via threadID
HHOOK mousehook = SetWindowsHookEx(WH_MOUSE_LL, (LRESULT (*)(int,WPARAM,LPARAM))arg,NULL, 0); // I am line 78
if (mousehook == NULL) printf("Mousehook error %lu\n",GetLastError());
//...
}
It makes no sense because I am casting to the exact type that it expects to receive, there aren't any qualifiers or anything that are different. What could possibly be going on here?
The compiler is omitting the calling convention from the error message -- SetWindowsHookEx wants a LRESULT (__stdcall *)(int,WPARAM,LPARAM), but you're passing it a LRESULT (__cdecl *)(int,WPARAM,LPARAM).
First, don't cast function pointers to void *. It is never safe to invoke a function of one type after casting it to another, and so there's rarely, if ever, a need to make them void *.
Second, probably you're seeing a difference in calling conventions. The type of the hook parameter is, properly stated, (LRESULT (CALLBACK *) (int, WPARAM, LPARAM)), or simply HOOKPROC. The prototype of the function should look like LRESULT CALLBACK MouseHookProc(int, WPARAM, LPARAM). Most likely gcc doesn't pretty-print the calling-convention specifier, but does check for it when checking type equivalence. Subtle problems like this are another reason not to cast function pointers - had you used a (HOOKPROC) cast, you would have had no compile-time error, but could have crashed at runtime .... but only on certain versions of windows.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With