Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange "invalid conversion from <type> to <type>" error

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?

like image 297
Steven Lu Avatar asked Sep 15 '26 08:09

Steven Lu


2 Answers

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).

like image 179
ildjarn Avatar answered Sep 17 '26 01:09

ildjarn


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.

like image 41
bdonlan Avatar answered Sep 17 '26 02:09

bdonlan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!