Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

c++ - Can't we use threads inside the member function of class?

This is mine base class

class IDialysisConnector
    {
    public:
    HANDLE threadHandle_;   
    virtual int ConnectToMachine();  //This will make socket connection with the machine.
    virtual void WINAPI ServerConnectThread(LPVOID lpdwThreadParam)=0;
    };

Another class

class A:public IDialysisConnector
{

int ConnectToMachine()
{

    int conResult,iResult;;
    struct addrinfo           *result = NULL,*ptr = NULL;

    u_long iMode = 0;
    DWORD nTimeout = 5000; // 5 seconds
    int port=22;
    WSADATA wsaData;

    // Initialize Winsock

    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) 
    {
        printf("WSAStartup failed with error: %d
", iResult);

    }

    ZeroMemory( &addr_, sizeof(addr_) );
    addr_.ai_family = AF_UNSPEC;
    addr_.ai_socktype = SOCK_STREAM;
    addr_.ai_protocol = IPPROTO_TCP;

    // Resolve the server address and port
    conResult = getaddrinfo("192.168.15.168", (PCSTR)22, &addr_, &result);
    if ( conResult != 0 ) {
        printf("getaddrinfo failed with error: %d
", conResult);
        WSACleanup();
        return 1;
    }

    // Attempt to connect to an address until one succeeds
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

        // Create a SOCKET for connecting to server
        sock_ = socket(ptr->ai_family, ptr->ai_socktype, 
            ptr->ai_protocol);
        if (sock_ == INVALID_SOCKET) {
            printf("socket failed with error: %ld
", WSAGetLastError());
            WSACleanup();
            return 1;
        }
            conResult = ioctlsocket(sock_, FIONBIO, &iMode);
        if (conResult != NO_ERROR)
            printf("ioctlsocket failed with error: %ld
", conResult);


        conResult = setsockopt(sock_, SOL_SOCKET, SO_RCVTIMEO, (const char*)&nTimeout, sizeof(DWORD));
        if (conResult != NO_ERROR)
        {
            printf("
Setsocopt fail with error :%d
",WSAGetLastError());

            return 0;
        }


        // Connect to server.
        conResult = connect(sock_, ptr->ai_addr, (int)ptr->ai_addrlen);
        if (conResult == SOCKET_ERROR) {
            closesocket(sock_);
            sock_ = INVALID_SOCKET;
            continue;
        }
        break;
    }

    freeaddrinfo(result);

    if (sock_ == INVALID_SOCKET) {
        printf("Unable to connect to server!
");
        WSACleanup();
        return 1;
    }
    DWORD dwThreadId;
    //threadHandle_=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ServerConnectThread,this,0,&dwThreadId);
        threadHandle_=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,this,0,&dwThreadId);
   void WINAPI IDialysisConnector::ServerConnectThread(LPVOID lpdwThreadParam)
    {
SOCKET ThreadSocket = INVALID_SOCKET;
    ThreadSocket=(SOCKET)lpdwThreadParam;
    while(1)
    {
        SendRequest(ThreadSocket);
        ReceiveResponse(ThreadSocket);
        Sleep(10000);
    }
        }

static UINT ThreadFunc(LPVOID param) {
IDialysisConnector* obj = (IDialysisConnector*)param;
obj->ServerConnectThread(); // call the member function
// to do the work in our new thread }

}

}

I did like this too but same error

threadHandle_=CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)IDialysisConnector::ServerConnectThread,(LPVOID)sock_,0,&dwThreadId);

I am getting an error that is

" error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'LPTHREAD_START_ROUTINE'"
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

No, CreateThread expects a plain function pointer, which is quite different from a pointer to a non-static C++ member function.

You have to create a normal function for the function you give CreateThread. That function can act as a trampoline back to the C++ world, e.g.

static UINT WINAPI ThreadFunc(LPVOID param)
{
   IDialysisConnector* obj = (IDialysisConnector*)param;
   obj->ServerConnectThread(); // call the member function
                               // to do the work in our new thread
}

Then your ConnectToMachine becomes:

int ConnectToMachine()
{
    DWORD dwThreadId;
    //give 'this' as the thread param to ThreadFunc
    threadHandle_=CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)ThreadFunc,(LPVOID)this,0,&dwThreadId);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...