简体   繁体   English

LNK2019:未解析的外部符号

[英]LNK2019: Unresolved external symbol

I've seen plenty of other questions like this but I just couldn't figure this problem out with the help of them. 我已经看到了很多其他类似的问题,但我无法在他们的帮助下解决这个问题。 I've understood that it's a linking problem but from what I can see, I've got the linking straightened out. 我知道这是一个链接问题,但从我所看到的,我已经把连接理顺了。

I'm writing a chat server/client (with the help of this article ). 我正在写一个聊天服务器/客户端(在本文的帮助下)。

I've defined a class to hold the server functions and have a header-file that handles all the includes. 我已经定义了一个类来保存服务器函数,并有一个处理所有包含的头文件。

This is the header file: 这是头文件:

#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);
};

This is the actual server "class": 这是实际的服务器“类”:

#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);

    }

And lastly, the main.cpp file with the entry-method for the program calls "ChatServer::InitServer(g_hInst)". 最后,带有程序入口方法的main.cpp文件调用“ChatServer :: InitServer(g_hInst)”。 It's pretty big so I omitted it but if it's needed I'll post it aswell. 它很大,所以我省略了它但是如果它需要的话我会发布它。

The error messages I'm getting are like the one below but they all state problems with the api-functions related to winsockets API: 我得到的错误消息如下所示,但它们都表明与winsockets API相关的api函数存在问题:

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

As I stated before, I believe this problem has something to do with the compiler misunderstanding what to do with functions like "closesocket" that should be linked to winsock.h. 正如我之前所说,我认为这个问题与编译器误解如何处理应该链接到winsock.h的“closesocket”等功能有关。

Thanks for any advice at all and thanks for reading all of this gibberish :) 感谢任何建议,感谢阅读所有这些乱码:)

These linker errors are always the same: you're using a symbol that the linker cannot find. 这些链接器错误始终相同:您使用链接器无法找到的符号。 You need to tell the linker to link with the libraries that contain those symbols. 您需要告诉链接器链接包含这些符号的库。

As I stated before, I believe this problem has something to do with the compiler misunderstanding what to do with functions like "closesocket" that should be linked to winsock.h. 正如我之前所说,我认为这个问题与编译器误解如何处理应该链接到winsock.h的“closesocket”等功能有关。

No, closesocket is not linked to winsock.h. 不, closesocket没有链接到winsock.h。 winsock.h is a header file, not a library. winsock.h是头文件,而不是库。 It may contain a declaration of closesocket and that's ok for the compiler, but the linker really needs to know where the code of that function is so it can link your program to it. 它可能包含closesocket的声明,这对编译器来说没问题,但链接器确实需要知道该函数的代码在哪里,以便它可以将程序链接到它。

You should probably be using winsock2.h instead of winsock.h, though. 但是你可能应该使用winsock2.h而不是winsock.h。 The Windows Sockets API 2.0 dates from 1994, and version 1 is long obsolete. Windows Sockets API 2.0的历史可以追溯到1994年,版本1已经过时了。

You can see at the bottom of this function's documentation that the library where it resides is ws2_32.lib. 您可以在此函数的文档底部看到它所在的库是ws2_32.lib。

Your class can be defined like so: 您的类可以这样定义:

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

However you're error is caused by not including the library input. 但是,错误是由于不包括库输入引起的。 On your project input line add the dependency on winsock library also consider using winsock2.h. 在你的项目输入行上添加对winsock库的依赖也考虑使用winsock2.h。

For reference: http://msdn.microsoft.com/en-us/library/ms737629(v=vs.85).aspx 供参考: http//msdn.microsoft.com/en-us/library/ms737629(v = vs。85).aspx

Just including the .h file does not cause the actual code that implements the functions to be linked in. The .h file tells the compiler that the functions exist somewhere, and what their signature is. 仅包含.h文件不会导致实现函数的实际代码被链接..h文件告诉编译器函数存在于某处,以及它们的签名是什么。 You still have to make the library where the function is actually implemented available to the linker. 您仍然必须使实际实现该功能的库可用于链接器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM