Jump to content

  • Log In with Google      Sign In   
  • Create Account

#Actualcdoubleplusgood

Posted 17 September 2013 - 01:35 AM

How to convert the function pointer in a class to the normal function pointer in C?

You cannot directly specify an instance method as method / callback parameter in Windows API in general, and not in CreateThread in particular. This is because internally instance methods have an additional parameter pointing to the class instance, so the method signature does not match the signature required by CreateThread.
The usual workaround is to have a static method, pass a pointer to the instance as lpParameter, and dispatch the call in the static method to an instance method, using that parameter.

class MsgListener
{
private:
    HANDLE _threadHandle;
    DWORD _threadId;
    static MsgListener *_instance;
    MsgListener();
    DWORD Listen();
    static DWORD WINAPI StaticListen(LPVOID param);
public:
    static MsgListener *GetInstance();
    void StartListen();
    void StopListen();
};

MsgListener *MsgListener::_instance = new MsgListener();
MsgListener::MsgListener() 
{ 
    _threadHandle = 0;
    _threadId = 0;
}
DWORD WINAPI MsgListener::StaticListen(LPVOID param) 
{
	MsgListener* listener = reinterpret_cast<MsgListener*>(param);
	return listener->Listen();
}
DWORD MsgListener::Listen() 
{ 
    // The method to run in a new thread....
	return 0;
}
MsgListener *MsgListener::GetInstance()
{
    if (!_instance)
        _instance = new MsgListener();
    return _instance;
}
void MsgListener::StartListen()
{
    this->_threadHandle = CreateThread(NULL, 0, &MsgListener::StaticListen, this, 0, &_threadId);
}
void MsgListener::StopListen()
{
    CloseHandle(_threadHandle);
}

However, I'd use the threading support in C++11 instead. It is so much easier to specify an arbitrary worker method, even an instance method, using the std::thread ctor:

http://en.cppreference.com/w/cpp/thread/thread/thread


#2cdoubleplusgood

Posted 17 September 2013 - 01:32 AM

How to convert the function pointer in a class to the normal function pointer in C?

You cannot directly specify an instance method as method / callback parameter in Windows API in general, and not in CreateThread in particular. This is because internally instance methods have an additional parameter pointing to the class instance, so the method signature does not match the signature required by CreateThread.
The usual workaround is to have a static method, pass a pointer to the instance as lpParameter, and dispatch the call in the static method to an instance method, using that parameter.

class MsgListener
{
private:
    HANDLE _threadHandle;
    DWORD _threadId;
    static MsgListener *_instance;
    MsgListener();
    DWORD Listen();
    static DWORD WINAPI StaticListen(LPVOID param);
public:
    static MsgListener *GetInstance();
    void StartListen();
    void StopListen();
};

MsgListener *MsgListener::_instance = new MsgListener();
MsgListener::MsgListener() 
{ 
    _threadHandle = 0;
    _threadId = 0;
}
DWORD WINAPI MsgListener::StaticListen(LPVOID param) 
{
	MsgListener* listener = reinterpret_cast<MsgListener*>(param);
	return listener->Listen();
}
DWORD MsgListener::Listen() 
{ 
    // The method to run in a new thread....
	return 0;
}
MsgListener *MsgListener::GetInstance()
{
    if (!_instance)
        _instance = new MsgListener();
    return _instance;
}
void MsgListener::StartListen()
{
    this->_threadHandle = CreateThread(NULL, 0, &MsgListener::StaticListen, MsgListener::GetInstance(), 0, &_threadId);
}
void MsgListener::StopListen()
{
    CloseHandle(_threadHandle);
}

However, I'd use the threading support in C++11 instead. It is so much easier to specify an arbitrary worker method, even an instance method, using the std::thread ctor:

http://en.cppreference.com/w/cpp/thread/thread/thread


#1cdoubleplusgood

Posted 17 September 2013 - 01:31 AM

How to convert the function pointer in a class to the normal function pointer in C?

You cannot directly specify an instance method as method parameter in Windows API in general, and not in CreateThread in particular. This is because internally instance methods have an additional parameter pointing to the class instance, so the method signature does not match the signature required by CreateThread.
The usual workaround is to have a static method, pass a pointer to the instance as lpParameter, and dispatch the call in the static method to an instance method, using that parameter.

class MsgListener
{
private:
    HANDLE _threadHandle;
    DWORD _threadId;
    static MsgListener *_instance;
    MsgListener();
    DWORD Listen();
    static DWORD WINAPI StaticListen(LPVOID param);
public:
    static MsgListener *GetInstance();
    void StartListen();
    void StopListen();
};

MsgListener *MsgListener::_instance = new MsgListener();
MsgListener::MsgListener() 
{ 
    _threadHandle = 0;
    _threadId = 0;
}
DWORD WINAPI MsgListener::StaticListen(LPVOID param) 
{
	MsgListener* listener = reinterpret_cast<MsgListener*>(param);
	return listener->Listen();
}
DWORD MsgListener::Listen() 
{ 
    // The method to run in a new thread....
	return 0;
}
MsgListener *MsgListener::GetInstance()
{
    if (!_instance)
        _instance = new MsgListener();
    return _instance;
}
void MsgListener::StartListen()
{
    this->_threadHandle = CreateThread(NULL, 0, &MsgListener::StaticListen, MsgListener::GetInstance(), 0, &_threadId);
}
void MsgListener::StopListen()
{
    CloseHandle(_threadHandle);
}

However, I'd use the threading support in C++11 instead. It is so much easier to specify an arbitrary worker method, even an instance method, using the std::thread ctor:

http://en.cppreference.com/w/cpp/thread/thread/thread


PARTNERS