LNK2019:无法解析的外部符号

问题描述:

我见过很多这样的其他问题,但我无法在他们的帮助下找出这个问题。我知道这是一个链接问题,但从我所看到的,我已经理清了链接。LNK2019:无法解析的外部符号

我在写一个聊天服务器/客户端(在this article的帮助下)。

我已经定义了一个类来容纳服务器函数,并且有一个头文件来处理所有的包含。

这是头文件:

#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)”。这是非常大的,所以我省略了它,但如果需要的话,我会发布它。

我收到错误消息就像是一个下方,但他们所有的状态问题,涉及到winsockets API的API函数:

Error 3 error LNK2019: unresolved external symbol [email protected] referenced in function "public: int __thiscall ChatServer::InitServer(struct HINSTANCE__ *)" ([email protected]@@[email protected]@@Z) 

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

感谢所有的任何意见,并感谢阅读这一切废话:)的

+1

你为什么不使用winsock2.h? – Drahakar

+5

你有链接与wininet.lib和ws2_32.lib? – stijn

+0

您不需要在每个成员函数声明前加上'public'。一旦列出访问说明符,在列出不同的访问说明符之前,所有后续内容都将具有相同的访问权限。 – Praetorian

这些链接错误都是一样的:您使用的符号链接器无法找到。您需要告诉链接器与包含这些符号的库链接。

正如我前面所说,我相信这个问题有事情做与 编译器误解如何处理应与WINSOCK.H像 “字关闭”功能做。

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

不过你应该使用winsock2.h而不是winsock.h。 Windows套接字API 2.0的日期从1994年开始,版本1早已过时。

您可以在this function's documentation的底部看到它所在的库是ws2_32.lib。

类可以被定义,像这样:

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

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