函数_main中未解析的外部符号“cSocket :: cSocket(void)”

时间:2011-02-15 04:12:21

标签: c++ visual-c++ constructor linker

#ifndef _ClientSocket_H_
#define _ClientSocket_H_

#include "Includes.h"
#include "LOGMSGs.h"

class cSocket
{
public:
    cSocket();
    bool Open();
    bool Listen(char *OnIP,int OnPort);
    void Send(char *MSG, int len);
    void Recv(char *MSG,int len);
    void Close();
protected:
    SOCKET  cSock;
    const int   SndBuf;
};

#endif


#include "ClientSocket.h"


bool cSocket::Open()
{
    WSADATA wsaData;
    int err;
    if((err =WSAStartup(0x202, &wsaData)) !=0)
    {
        Error("Init WSAStartup() failed[%d].", err);
        return false;
    }
    return true;
}

bool cSocket::Listen(char *OnIP,int OnPort)
{
    if(Open())
    {
        //Create the main socket
        cSock=socket(AF_INET, SOCK_STREAM, 0);
        if(cSock==INVALID_SOCKET)
        {
            int err = WSAGetLastError();
            //WSACleanup();
            printf("Init socket() failed[%d].", err);
            return FALSE;
        }

        //Set the REUSEADDR SOCKET
        int     optval = 1;
        if(setsockopt(cSock, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, sizeof(optval)))
        {
            int err = WSAGetLastError();
            Close();
            printf("Init setsockopt() SO_REUSEADDR failed[%d].", err);
            return FALSE;
        }

        //Set the KEEPALIVE SOCKET
        optval = 1;
        if(setsockopt(cSock, SOL_SOCKET, SO_KEEPALIVE, (char *) &optval, sizeof(optval)))
        {
            int err = WSAGetLastError();
            Close();
            printf("Init setsockopt() SO_KEEPALIVE failed[%d].", err);
            return FALSE;
        }

            // Set the SNDBUF SOCKET
        if(SndBuf)      // Non-0: pointer SNDBUG
        {
            optval = SndBuf;
            if(setsockopt(cSock, SOL_SOCKET, SO_SNDBUF, (char *) &optval, sizeof(optval)))
            {
                int err = WSAGetLastError();
                Close();
                printf("Init setsockopt() SO_SNDBUF failed[%d].", err);
                return FALSE;
            }

            // Read the SNDBUF SOCKET
            int ret = sizeof(optval);
            if(getsockopt(cSock, SOL_SOCKET, SO_SNDBUF, (char *) &optval, &ret) == 0)
            {
                LOGMSG("send buffer size SOCKET [%d] K.", optval/1024);
            }
        }

        SOCKADDR_IN     sin;
        memset(&sin, 0, sizeof(sin));
        sin.sin_family      = AF_INET;
        sin.sin_addr.s_addr = inet_addr(OnIP);
        sin.sin_port        = htons(OnPort);
        if(bind(cSock, (LPSOCKADDR) &sin, sizeof(sin)))
        {
            int err = WSAGetLastError();
            Close();
            printf("Init bind() failed[%d].", err);
            return FALSE;
        }

        //Set to non-blocking mode
        unsigned long   i = 1;
        if(ioctlsocket(cSock, FIONBIO, &i))
        {
            int err = WSAGetLastError();
            Close();
            printf("Init ioctlsocket() failed[%d].", err);
            return FALSE;
        }

        //Listening port
        if(listen(cSock, SOMAXCONN))        // SOMAXCONN: WIN macro definition
        {
            int err = WSAGetLastError();
            Close();
            printf("Init listen() failed[%d].", err);
            return FALSE;
        }
        return true;
    }
return false;
}


void cSocket::Close()
{
    closesocket(cSock);
    WSACleanup();
}


#include "Includes.h"
#include "LOGMSGs.h"
#include "auth_proto.h"
#include "Packets.h"
#include "ClientSocket.h"


int main(int argc, char* argv[]) 
{
    cSocket sock;
    while(1)
    {
        sock.Open();
        sock.Listen("127.0.0.1",4444);
    }
    return 0;
}
  

错误:函数_main

中引用的未解析的外部符号“public:__thiscall cSocket :: cSocket(void)”(?? 0cSocket @@ QAE @ XZ)

出了什么问题?

2 个答案:

答案 0 :(得分:5)

这是一个链接器错误,这意味着编译器已检查代码中是否包含语法错误,但链接器无法找到您尝试在程序中某处调用的函数的实现。在这种情况下,它找不到的功能是

__thiscall cSocket::cSocket(void)" (??0cSocket@@QAE@XZ) 

由于 name-mangling ,此函数看起来很神秘,其中编译器获取函数的源代码名称,然后以允许更好的类型安全链接的方式对其进行转换。但是,您仍然可以看到在此代码中的是函数名称

cSocket::cSocket(void)

这是cSocket的构造函数。如果您注意到,代码中没有您定义此构造函数,这就是链接器无法为其找到实现的原因。通过添加实现来修改代码应该有助于解决这个问题。

更一般地说,如果您看到这样的错误,通常意味着您已经通过函数原型或extern声明向编译器承诺某些函数或对象存在,但是没有给出包含其定义的链接器的目标文件。造成这种情况的主要原因通常是(大致按此顺序);

  1. 你原型化了一个功能,但忘了实现它。我想这就是发生在这里的事。
  2. 您构建了一个函数原型,但随后使用不同的签名实现了该函数。例如,如果您对函数void MyFunction(int)进行原型设计,然后将该函数实现为void MyFunction(int&)void MyFunction(),则链接器会认为这是一个重载而不是实现,并会给您错误在链接时而不是编译时。
  3. 您使用定义编译了代码,但没有将其链接。如果您有一个多文件项目然后忘记将其中一个文件作为输入传递给链接器,则可能会发生这种情况。
  4. 希望这有帮助!

答案 1 :(得分:2)

您没有声明构造函数定义

cSocket::cSocket()
{
    //your init code here
}

如果您不打算使用构造函数,那么只需从类声明中删除行cSocket();