帐前卒专栏

Without software, we are nothing.

Error LNK2019 Unresolved External Symbol

Today I have found this problem :

error LNK2019: unresolved external symbol impgethostname@8 referenced in function _wmain

and

fatal error LNK1120: 1 unresolved externals

code fragment is :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// if this code fragment can be compiled, the result will not be your expected.

#include "stdafx.h"
#include <iostream>
#include <WinSock2.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
  const int len = 256;
  char buffer[len];
  int a = gethostname(buffer,len);
  cout <<a<<endl; // a will be -1
  cout << buffer<<endl; // buffer will be filled with unreadable code.
  return 0;
}

What’s wrong?

If you don’t add #include <WinSock2.h>, the compiler will report :  error C3861: ‘gethostname’: identifier not found . But after you adding this header, it will report above error again.  First, you should add the header <afxext.h> into stdafx.h, then compile the code again. Code will be compiled without any error. Then run this code fragment, and the result is not my expected. a is -1, and the buffer is filled with messy code. If you use WSAGetLastError() function to see it error code, the error code will be WSANOTINITIALISED. Yes, I have not initialized. So we should call WSAStartup() first and then gethostname. And WSAStartup() will check DLL version. And after having gotten hostname, don’t forget to call WSACleanup(). Here is the whole code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "stdafx.h"
//#include <winsock.h>
#include <iostream>
#include <WinSock2.h> // use winsock2.h is ok
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
  const int len = 256;
  char buffer[len];
  WORD wVersionRequested;
  WSADATA wsaData;
  wVersionRequested = MAKEWORD(2,2); //version 2.2 
  int err = WSAStartup(wVersionRequested,&wsaData);
  if (0 != err) return 1;
  if ( LOBYTE( wsaData.wVersion ) != 2 ||
        HIBYTE( wsaData.wVersion ) != 2 ) {
               // only support version 2.2 of Windows Sockets 
          WSACleanup();
          return 1;
  }
  // get hostname
  int a = gethostname(buffer,len);
  /* if there is an error. use WSAGetLastError to find it.
  int errcode = WSAGetLastError();
  switch(errcode){
   ....
  }*/
  cout << buffer<<endl;
  WSACleanup();
  return 0;
}

Comments