invalid conversion from 'DWORD (*)(void*)' to 'DWORD (*)(void*)' - c++

invalid conversion from 'DWORD (*)(void*)' to 'DWORD (*)(void*)' .
cake==lie
1==0
I have no idea what this means ... I get it in this code
HANDLE CPlugin::CreateWinampThread() ||
{ __VVVVVVVV__
hWinampThreadHandle = (HANDLE)CreateThread(NULL, 0, StartWinampThread, (void*)this, 0, &dwWinampThreadID);
if (!hWinampThreadHandle)
return 0;
CloseHandle(hWinampThreadHandle);
return hWinampThreadHandle;
}
.
DWORD WINAPI CPlugin::StartWinampThread(void* lpParam)[...]

StartWinampThread must be static if it is member function.

See here: in-c-is-it-safe-portable-to-use-static-member-function-pointer-for-c-api-callb for why you need to use a extern "C"
The correct way would be somthing like this:
HANDLE CPlugin::CreateWinampThread() ||
{ __VVVVVVVV__
hWinampThreadHandle = (HANDLE)CreateThread(NULL, 0, ::StartWinampThread, (void*)this, 0, &dwWinampThreadID);
if (!hWinampThreadHandle)
return 0;
CloseHandle(hWinampThreadHandle);
return hWinampThreadHandle;
}
.
// A callback function for C code must have C linkage.
// That is not possable for C++ static member functions.
extern "C" DWORD WINAPI StartWinampThread(void* lpParam)
{
// You can always call your static member function here.
CPlugin::StartWinampThread(lpParam)
}

Is it to do with objects - there's an implicit 'this' paramter to your object's StartWinampThread method because it's a member of a class.
What happens if you change it to be a standalone method but keep the same signature i.e. from
DWORD WINAPI CPlugin::StartWinampThread(void* lpParam)[...]
to
DWORD WINAPI StartWinampThread(void* lpParam)[...]
(I know it won't work for you, I'm just interested to see if it removes the compiler's complaint)

Related

How to use WlanRegisterNotification function

I want to register wlan notification.
Code:
HANDLE hClient;
DWORD dwResult = 0;
DWORD dwPrevNotif = 0;
dwResult = WlanRegisterNotification(hClient, WLAN_NOTIFICATION_SOURCE_ALL, TRUE, NotificationCallback, NULL, NULL, &dwPrevNotif);
void WINAPI WirelessConnect::NotificationCallback(PWLAN_NOTIFICATION_DATA wlanData, PVOID context)
{
}
The problem is:
error: C3867: 'WirelessConnect::NotificationCallback': non-standard syntax; use '&' to create a pointer to member
When I use &NotificationCallback I get error:
error: C2276: '&': illegal operation on bound member function expression
How to fix it? Thanks.
You are trying to pass a pointer to a member function as a callback, that is - as a function pointer. You shouldn't do that, member function pointers are meaningless without the object itself.
You should make your callback a static function, that way there are no objects involved.

My WlanRegisterNotification callback is only working when the callback is static

I have been struggling for days to figure out the probably obvious reason why i cant get my code to compile.
I have a class (based on wxThread) where the callback is defined:
-- Header file --
class TestClass : public wxThread
{
private:
static void WlanNotification(WLAN_NOTIFICATION_DATA *wlanNotifData, VOID *p);
};
-- Code file --
I call the WlanRegisterNotification function, that needs the above callback function as a parameter:
dwResult = WlanRegisterNotification(hClient, WLAN_NOTIFICATION_SOURCE_ALL, true, (WLAN_NOTIFICATION_CALLBACK) WlanNotification, this, 0, &dwPrevNotif);
This compiles and works fine, but the problem is the function is marked as static, so i cant access my non static stuff from the callback (which i need for other reasons).
I have tried every single combination i can think of to pass in the callback as non static:
-- Header file --
void WINAPI WlanNotification(PWLAN_NOTIFICATION_DATA data, PVOID context);
-- Code file --
dwResult = WlanRegisterNotification(hClient, WLAN_NOTIFICATION_SOURCE_ALL, true, (WLAN_NOTIFICATION_CALLBACK)WlanNotification, this, 0, &dwPrevNotif);
i just get:
error C2660: 'WlanRegisterNotification' : function does not take 6
arguments
error C2440: 'type cast' : cannot convert from 'overloaded-function'
to 'WLAN_NOTIFICATION_CALLBACK'
I'm thinking its related to the typedef somehow:
typedef VOID (WINAPI *WLAN_NOTIFICATION_CALLBACK) (PWLAN_NOTIFICATION_DATA, PVOID);
I have tried googling for examples of using the WlanRegisterNotification function, but none of the examples i could find is calling it from a class, which is what seems to be an issue here, so i'm really lost.
A non-static class method has a hidden this parameter that the callback is not expecting let alone know how to fill in. That is why you cannot use it as a callback unless you either 1) use static to remove that parameter, or 2) create a thunk to use as the actual callback and then have it internally delegate to a non-static class method. Remember that the Windows API is designed for C, not C++. There are no classes or implicit this pointers in C.
In this case, a static callback can access non-static members of your class because you are explicitly passing the object's this pointer as the pCallbackContext of WlanRegisterNotification(), which is then passed as-is to the context of the callback:
class TestClass : public wxThread
{
private:
static VOID WINAPI WlanNotification(PWLAN_NOTIFICATION_DATA wlanNotifData, PVOID context);
};
VOID WINAPI TestClass::WlanNotification(PWLAN_NOTIFICATION_DATA wlanNotifData, PVOID context)
{
TestClass *pThis = (TestClass*) context;
// use pThis-> to access non-static members as needed..
}
// get rid of the typecast when passing the callback. If it does
// not compile, then it is not declared in a compatible manner...
dwResult = WlanRegisterNotification(hClient, WLAN_NOTIFICATION_SOURCE_ALL, TRUE, &WlanNotification, this, 0, &dwPrevNotif);

c++ Modify drivers, got "cannot convert from overloaded function" error

Im modifiy my display drivers to get update notifcation sent from the USB port. So far so good, but i got stock on follow:
GPEFlat::GPEFlat()
{
PBOOT_ARGS args;
ULONG fbSize;
ULONG fbOffset;
ULONG offsetX;
ULONG offsetY;
BOOL bFoundArgs = FALSE;
BOOL m_MouseDisabled = TRUE;
HANDLE m_hAttachEvent = CreateEvent(NULL, FALSE, FALSE, L"MouseAttached");
HANDLE m_hDetachEvent = CreateEvent(NULL, FALSE, FALSE, L"MouseDetached");
HANDLE m_hCursorThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MouseEventThread, NULL, 0, NULL);
DWORD
GPEFlat::MouseEventThread(void)
{
DWORD rc = TRUE;
HANDLE handles[2];
handles[0] = m_hAttachEvent;
handles[1] = m_hDetachEvent;
The resulting error is:
Error 1 error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'LPTHREAD_START_ROUTINE' drivers\display\vgaflat
So the line : HANDLE m_hCursorThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MouseEventThread, NULL, 0, NULL);
Dosnt work. Got some pointers that it may be to non static method.
How should i do this?
Greetings
The thing to understand is that functions (including static methods) and non-static methods are different things. CreateEvent expects a function. You must give it that, it will not work with GPEFlat::MouseEventThread because that's a method. What you can do though is give it a function which calls GPEFlat::MouseEventThread. Usually this is done like this
DWORD WINAPI thread_starter(LPVOID that)
{
return ((GPEFlat*)that)->MouseEventThread();
}
...
CreateThread(NULL, 0, thread_starter, this, 0, NULL);
Note that I pass this to CreateThread, that's very important. CreateThread passes it to the parameter that in thread_starter, which uses that to call the method you wanted to call all along.
The MouseEventThread have to be a static function, because a function pointer is not the same as a member function pointer. Static methods can be used as normal function pointers, but non-static member functions can not.
If you need to reference class members, then one very simple solution is to have a static wrapper functions, which takes the instance of the object (this in the constructor) and then calls the actual member function using that instance pointer.
Something like
class GPEFlat
{
// ...
private:
static DWORD MouseEventThreadWrapper(LPVOID instance)
{ return reinterpret_cast<GPEFlat*>(instance)->MouseEventThread(); }
// ...
};
Create the thread with this wrapper function instead, passing this as argument to it:
GPEFlat::GPEFlat()
{
// ...
HANDLE m_hCursorThread = CreateThread(
NULL, 0, (LPTHREAD_START_ROUTINE)MouseEventThreadWrapper, this, 0, NULL);
}

Error of argument type with _beginthreadex

To define my thread I have in my Header file:
class HttpClient
{
public:
...
unsigned int __stdcall PerformLogin(void*);
...
};
Then in my cpp file I have:
unsigned int __stdcall PerformLogin(void*){
...
}
And to call this thread I use
hThread = (HANDLE)_beginthreadex( NULL, 0, &PerformLogin, NULL, 0, &threadID );
But i Have an error on the &PerformLogin saying that:
the args of type unsigned int (__stdcall HttpClient::)(void) is not compatible with the param unsigned int (__stdcall*)(void*).
I understand the error, but I really don't know how to fix this!
A possible way to fix this would be to make the member function static, though this means PerformLogin() does not have a this pointer and would have no access to non-static members of HttpClient.
Another is to move PerformLogin() out of HttpClient altogether, and make it a free function.
What I usually to is to add 'this' as the void* parameter to the static function - you can then call methods on it in the static function with a bit of casting..
Member functions get this pointer implicitly as a first parameter.
So if you want to start a thread with a class member function, you should explicitly pass a pointer to a class instance in your call to _beginthreadex.
So, remove explicit argument:
class HttpClient
{
public:
...
unsigned int __stdcall PerformLogin();
...
};
And call _beginthreadex while passing this as an argument:
hThread = (HANDLE)_beginthreadex( NULL, 0, &PerformLogin, this, 0, &threadID );
It's worth mentioning that this is a bit hacky. C++ FAQ advises against it.
I still prefer this approach. Of course I just use boost::thread usually.

no instance of overloaded function "AfxBeginThread" matches the argument list

am trying to make a worker thread using MFC so here is the codes:
struct ThreadParam
{
HWND mDlg; // Note: A handle.
};
UINT TestMFCThread::Test( LPVOID pParam ){
//do work!
}
void TestMFCThread::OnBnClickedButton2()
{
ThreadParam* param = new ThreadParam;
param->mDlg = m_hWnd;
AfxBeginThread(Test, param);
}
but it gives me this error :
1 IntelliSense: no instance of overloaded function "AfxBeginThread" matches the argument list
argument types are: (UINT (LPVOID pParam), ThreadParam *)
idk whats wrong it's supposed to be right!
From the documentation for AfxBeginThread() you need to cast the second argument to LPVOID:
AfxBeginThread(Test, (LPVOID) param);
and set calling convention of Test to __cdecl:
UINT __cdecl Test( LPVOID lParam)
just declare your member function as static , it will solve the issue