LNK2019:未解析的外部符号

发布于 2024-12-02 05:25:43 字数 3855 浏览 0 评论 0原文

我见过很多类似的问题,但在他们的帮助下我无法解决这个问题。我知道这是一个链接问题,但从我所看到的来看,我已经理顺了链接。

我正在编写一个聊天服务器/客户端(在本文的帮助下) 。

我定义了一个类来保存服务器函数,并有一个处理所有包含内容的头文件。

这是头文件:

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

    }

最后,带有程序调用“ChatServer::InitServer(g_hInst)”入口方法的 main.cpp 文件。它相当大,所以我省略了它,但如果需要的话我也会发布它。

我收到的错误消息类似于下面的错误消息,但它们都说明了与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)  

正如我之前所说,我相信这个问题与编译器误解如何处理类似的函数有关“closesocket”应该链接到winsock.h。

感谢您的任何建议,也感谢您阅读所有这些胡言乱语:)

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)". 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:

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.

Thanks for any advice at all and thanks for reading all of this gibberish :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

長街聽風 2024-12-09 05:25:43

这些链接器错误始终是相同的:您使用的是链接器找不到的符号。您需要告诉链接器链接包含这些符号的库。

正如我之前所说,我相信这个问题与
编译器误解了如何处理类似的函数
“closesocket”应该链接到winsock.h。

不,closesocket 未链接到winsock.h。 winsock.h 是一个头文件,而不是一个库。它可能包含 closesocket 声明,这对编译器来说没问题,但链接器确实需要知道该函数的代码在哪里,以便将您的程序链接到它。

不过,您可能应该使用winsock2.h 而不是winsock.h。 Windows Sockets API 2.0 可以追溯到 1994 年,版本 1 早已过时。

您可以在此函数的文档底部看到该函数所在的库驻留在ws2_32.lib。

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.

No, closesocket is not linked to winsock.h. winsock.h is a header file, not a library. 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.

You should probably be using winsock2.h instead of winsock.h, though. The Windows Sockets API 2.0 dates from 1994, and version 1 is long obsolete.

You can see at the bottom of this function's documentation that the library where it resides is ws2_32.lib.

秋日私语 2024-12-09 05:25:43

您的类可以这样定义:

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

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.

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

自演自醉 2024-12-09 05:25:43

仅包含 .h 文件不会导致链接实现函数的实际代码。.h 文件告诉编译器这些函数存在于某处,以及它们的签名是什么。您仍然必须使实际实现该函数的库可供链接器使用。

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. You still have to make the library where the function is actually implemented available to the linker.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文