LNK2019: Неразрешенный внешний символ - PullRequest
4 голосов
/ 29 августа 2011

Я видел много других подобных вопросов, но я просто не мог разобраться с этой проблемой.Я понял, что это проблема связывания, но из того, что я вижу, я исправил связь.

Я пишу чат-сервер / клиент (с помощью этой статьи ).

Я определил класс для хранения функций сервера и имеюзаголовочный файл, который обрабатывает все включения.

Это заголовочный файл:

#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#include <tchar.h>
#include <strsafe.h>
#include "resource1.h"


class ChatServer
{
    public: int InitServer(HINSTANCE hInst);

    public: void ReportError(int errorCode, const char *whichFunc);
};

Это фактический "класс" сервера:

#include "server.h"
#define NETWORK_ERROR -1
#define NETWORK_OK     0
//Keeps stuff for the server    
int ChatServer::InitServer(HINSTANCE hInst)
    {
        WORD sockVersion;
        WSADATA wsaData;
        int nret;

        sockVersion = MAKEWORD(1,1); //Version 1.1

        //Init winsock
        WSAStartup(sockVersion, &wsaData);

        //Create listening socket
        SOCKET listeningSocket;

        //AFINET - Go over TCP
        //SOCK_STREAM - Stream oriented socket
        //IPPROTO_TCP - Use tcp rather than udp
        listeningSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP);

        if(listeningSocket == INVALID_SOCKET)
        {
            nret = WSAGetLastError(); //Get error detail
            ReportError(nret, "socket()");

            WSACleanup();

            return NETWORK_ERROR;
        }

        SOCKADDR_IN serverInfo;

        serverInfo.sin_family = AF_INET;
        serverInfo.sin_addr.s_addr = INADDR_ANY;
        serverInfo.sin_port = htons(1337); 

        //Bind the socket to local server address.
        nret = bind(listeningSocket, (LPSOCKADDR)&serverInfo, sizeof(struct sockaddr));

        if(nret == SOCKET_ERROR)
        {
            nret = WSAGetLastError();
            ReportError(nret, "bind()");
            WSACleanup();
            return NETWORK_ERROR;
        }

        //Make socket listen
        nret = listen(listeningSocket, 10); //Up to 10 connections at the same time.

        if(nret = SOCKET_ERROR)
        {
            nret = WSAGetLastError();
            ReportError(nret, "listen()");
            WSACleanup();
            return NETWORK_ERROR;
        }

        //Wait for client
        SOCKET theClient;
        theClient = accept(listeningSocket, NULL, NULL);

        if(theClient == INVALID_SOCKET)
        {
            nret = WSAGetLastError();
            ReportError(nret, "accept()");
            WSACleanup();
            return NETWORK_ERROR;
        }

        //Send and receive from the client, and finally,
        closesocket(theClient);
        closesocket(listeningSocket);

        //shutdown
        WSACleanup();
        return NETWORK_OK;
    }



void ChatServer::ReportError(int errorCode, const char *whichFunc)

    {

       char errorMsg[92];                   // Declare a buffer to hold
                                            // the generated error message
       ZeroMemory(errorMsg, 92);            // Automatically NULL-terminate the string
       // The following line copies the phrase, whichFunc string, and integer errorCode into the buffer
       sprintf(errorMsg, "Call to %s returned error %d!", (char *)whichFunc, errorCode);



       MessageBox(NULL, errorMsg, "socketIndication", MB_OK);

    }

И, наконец, файл main.cpp с записью-метод для вызова программы "ChatServer :: InitServer (g_hInst)".Он довольно большой, поэтому я пропустил его, но если понадобится, я также опубликую его.

Сообщения об ошибках, которые я получаю, похожи на приведенные ниже, но все они указывают на проблемы с API-функциями, связанными с winsockets API.:

Error   3   error LNK2019: unresolved external symbol _closesocket@4 referenced in function "public: int __thiscall ChatServer::InitServer(struct HINSTANCE__ *)" (?InitServer@ChatServer@@QAEHPAUHINSTANCE__@@@Z)  

Как я уже говорил ранее, я считаю, что эта проблема связана с неправильным пониманием компилятором того, что делать с такими функциями, как "closesocket", которые должны быть связаны с winsock.h.

Спасибо за любые советы и спасибо за чтение всего этого бреда:)

Ответы [ 3 ]

9 голосов
/ 29 августа 2011

Эти ошибки компоновщика всегда одинаковы: вы используете символ, который компоновщик не может найти. Вы должны указать компоновщику, чтобы он связывался с библиотеками, которые содержат эти символы.

Как я уже говорил ранее, я считаю, что эта проблема как-то связана с непонимание компилятором, что делать с такими функциями, как «closesocket», который должен быть связан с winsock.h.

Нет, closesocket не связан с winsock.h. winsock.h - это заголовочный файл, а не библиотека. Он может содержать объявление closesocket, и это нормально для компилятора, но компоновщик действительно должен знать, где находится код этой функции, чтобы он мог связать вашу программу с ним.

Возможно, вы должны использовать winsock2.h вместо winsock.h. Windows Sockets API 2.0 датируется 1994 годом, а версия 1 давно устарела.

Внизу вы можете увидеть документацию этой функции , что библиотека, в которой она находится, - это ws2_32.lib.

2 голосов
/ 29 августа 2011

Простое включение файла .h не приводит к тому, что фактический код, реализующий функции, должен быть связан. Файл .h сообщает компилятору, что функции где-то существуют и какова их сигнатура.Вам все еще нужно сделать библиотеку, в которой фактически реализована функция, доступной для компоновщика.

2 голосов
/ 29 августа 2011

Ваш класс может быть определен так:

class ChatServer
{
public:
    int InitServer(HINSTANCE hInst);
    void ReportError(int errorCode, const char *whichFunc);
};

Однако ваша ошибка вызвана отсутствием входных данных библиотеки.В строке ввода вашего проекта добавьте зависимость от библиотеки winsock и рассмотрите возможность использования winsock2.h.

Для справки: http://msdn.microsoft.com/en-us/library/ms737629(v=vs.85).aspx

...