0

这是我的基类

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

另一个班级

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\n", 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\n", 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\n", WSAGetLastError());
            WSACleanup();
            return 1;
        }
            conResult = ioctlsocket(sock_, FIONBIO, &iMode);
        if (conResult != NO_ERROR)
            printf("ioctlsocket failed with error: %ld\n", conResult);


        conResult = setsockopt(sock_, SOL_SOCKET, SO_RCVTIMEO, (const char*)&nTimeout, sizeof(DWORD));
        if (conResult != NO_ERROR)
        {
            printf("\nSetsocopt fail with error :%d\n",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!\n");
        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);
    }
        }

静态 UINT ThreadFunc(LPVOID 参数) {
IDialysisConnector* obj = (IDialysisConnector*)param;
obj->ServerConnectThread(); // 调用成员函数
// 在我们的新线程中完成工作 }

}

}

我也喜欢这个,但同样的错误

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

我收到一个错误是

" error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'LPTHREAD_START_ROUTINE'"
4

2 回答 2

3

不,CreateThread 需要一个普通的函数指针,这与指向非静态 C++ 成员函数的指针完全不同。

你必须为你给 CreateThread 的函数创建一个普通函数。该函数可以充当返回 C++ 世界的蹦床,例如

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

然后你的 ConnectToMachine 变成:

int ConnectToMachine()
{
    DWORD dwThreadId;
    //give 'this' as the thread param to ThreadFunc
    threadHandle_=CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)ThreadFunc,(LPVOID)this,0,&dwThreadId);
}
于 2012-10-11T13:46:13.660 回答
0

只能在对象上调用非静态成员函数。这就是为什么它的类型是指向成员函数而不是指向函数的指针CreateThread需要一个指向函数的指针,你不能给它一个指向成员函数的指针。

有些人会建议您将其设为static成员函数;这通常没问题,但我对只是为了使实施更容易而进行的设计更改持怀疑态度。如果它是一个非静态成员函数,那么,大概,它是一个非静态成员函数是有原因的。

您可以编写一个执行适当调用的函数:

void callback(void*p) {
    (IDialysisConnector*p)->ServerConnectThread();
}

并将其作为线程函数传递,并将适当对象的地址作为调用中的数据指针传递给CreateThread.

于 2012-10-11T13:44:39.737 回答