Hello,

I'm working on a simple winsock2 messaging program with a client and a server.

The server, which uses the same code as the client, save for some preprocessor directives, compiles fine, but the client throws up 3 unresovled external symbol errors:

Error 1 error LNK2019: unresolved external symbol "public: __thiscall Client::~Client(void)" (??1Client@@QAE@XZ) referenced in function _wmain Assignment 3 AIP 2 Client.obj

Error 2 error LNK2019: unresolved external symbol "public: int __thiscall Client::Connect(void)" (?Connect@Client@@QAEHXZ) referenced in function _wmain Assignment 3 AIP 2 Client.obj

Error 3 error LNK2019: unresolved external symbol "public: __thiscall Client::Client(void)" (??0Client@@QAE@XZ) referenced in function _wmain Assignment 3 AIP 2 Client.obj


I have linked the winsock2 library in both of the projects, but the client still throws up the errors. (Project->Properties->Configuration Properties->Linker->Input->Additional Dependencies->ws2_32.lib).

Any ideas as to why this might be?

Here is the code for the main function of the client:

#include "stdafx.h"
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include "windows.h"
#include "Client.h"
#include "Comms.h"
#include "Server.h"
#include <exception>
#include "Server.h"


#define CLIENT
//#define SERVER

char mutexName[] = "MUTEX1";

//*******************************************************
int _tmain(int argc, _TCHAR* argv[]){

#ifdef CLIENT

	try{
		Client myClient;
		myClient.Connect();
	}

	catch( NoDllException& e){
		cout << "Error 1 : " << e.what() << endl;
	}
	catch( ClientConnectException& e){
		cout << "Error 2 : " << e.what() << endl;
	}
	catch( ClientSocketException& e){
		cout << "Error 3 : " << e.what() << endl;
	}
	catch( ClientException& e){
		cout << "Error 4 : " << e.what() << endl;
	}
#endif

#ifdef SERVER

	try{
		Server myServer;
		myServer.Listen();
	}

	catch( ServerSocketException& e){
		cout << "Error 1 : " << e.what() << endl;
	}
	catch( BindFailedtException& e){
		cout << "Error 2 : " << e.what() << endl;
	}
	catch( ListenErrorException& e){
		cout << "Error 3 : " << e.what() << endl;
	}
	catch( SocketFailedException& e){
		cout << "Error 4 : " << e.what() << endl;
	}
	catch( GameNameException& e){
		cout << "Error 5 : " << e.what() << endl;
	}
	catch( RecieveClientException& e){
		cout << "Error 6 : " << e.what() << endl;
	}
	catch( ServerSendException& e){
		cout << "Error 7 : " << e.what() << endl;
	}

#endif

	
	system("pause");
	return 0;
}
//*******************************************************

It appears linker is not seeing the definitions for Client. Is Client.cpp compiled and linked with application?

It appears linker is not seeing the definitions for Client. Is Client.cpp compiled and linked with application?

Yes as far as I can see it is.

Can we see the client.h and client.cpp code?

Can we see the client.h and client.cpp code?

Here you go:

Client.h:

//===================================
//==== Assignment 3 =================
//==== Damien Parsons - 20830730 ====
//==== Date - 25/03/2011 ============
//==== Client.h =====================
//===================================

#pragma once
#include "stdafx.h"
#include <winsock2.h>
#include <ws2tcpip.h>
#include "iostream"
#include "windows.h"
#include "Comms.h"

//======================================================
class ClientConnectException: public exception {
public:
  virtual const char* what() const throw() {
    return "Client: connect() - Failed to connect.";
  }
};
//======================================================
class ClientSocketException: public exception {
public:
  virtual const char* what() const throw() {
    return "Error at socket()";
  }
};
//======================================================
class ClientException: public exception {
public:
  virtual const char* what() const throw() {
    return "Client: error %ld. ";
  }
};
//======================================================
class Client:
		public Comms
{
public:
	Client(void);
	~Client(void);
	char Enter();
	int Connect();

	char receiveBuffer[200];

	SOCKET clientSocket;
	
	ClientConnectException noConnection;
	ClientSocketException noSocket;
	ClientException cException;
};
//======================================================

and client.cpp:

//===================================
//==== Assignment 3 =================
//==== Damien Parsons - 20830730 ====
//==== Date - 25/03/2011 ============
//==== Client.cpp ===================
//===================================

#include "StdAfx.h"
#include "Client.h"
//*************************************************
Client::Client(void){
	char receiveBuffer[200] = "";
}
//*************************************************
Client::~Client(void){
}
//*************************************************
int Client::Connect() throw(ClientConnectException,ClientSocketException){
	
	cout<<"\n\n"<<endl;
	cout<<"\t\t=================="<<endl;
	cout<<"\t\t------CLIENT------"<<endl;
	cout<<"\t\t=================="<<endl;
	cout<<"\n\n"<<endl;

	this->createMySocket();

	clientSocket = INVALID_SOCKET;
	clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (clientSocket== INVALID_SOCKET){
		throw noSocket;
		cout <<  WSAGetLastError() << endl;
		WSACleanup();
		return 0;
	}
	else{
		cout << "socket() is OK!" << endl;
	}
	sockaddr_in clientService;
	clientService.sin_family = AF_INET;
	clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
	clientService.sin_port = htons(port);
	
	if (connect(clientSocket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR) {
		throw noConnection;
        WSACleanup();
        return 0;
	}
	else{
       cout << "Client: connect() is OK." << endl;
       cout << "Client: Can start sending and receiving data..." << endl;
	}
	
	Enter();
	return 0;
}
//*******************************************************
char Client::Enter(){

	char buffer[200]="";

	do{	
		printf("Enter your message ");
		cin.getline(buffer,200);

		int byteCount = send(clientSocket, buffer, 200, 0);

		if(byteCount == SOCKET_ERROR){
			printf("Server send error %ld.\n", WSAGetLastError());
			return -1;
		}
		char receiveBuffer[200] = "";
		int byteCount2 = recv(clientSocket, receiveBuffer, 200, 0);
		if (byteCount2 < 0){
			throw cException;
			WSAGetLastError();
			return 0;
		}
		else { 
		    printf("Received data :  %s  \n", receiveBuffer);
		}
		char buffer[200]="";
	}while(strcmp(buffer,"QUIT")!= 0);

	WSACleanup(); 
	return 0;	
}

The simple sample below creates a similar error, if the definition of ~Client is missing. In your case althought the definition exists, the linker seems to not see it. When I get into this type of problem, I strip the code to its bare essentials and usually the problem becomes obvious.

class Client
{
public:
Client();
~Client();
};

Client::Client()
{
}

#ifdef MISSING
Client::~Client()
{
}
#endif
 
int main()
{
   Client c;
   return 0;
}
 
test2.obj : error LNK2019: unresolved external symbol "public: __thiscall Client::~Client(void)" (??1Client@@QAE@XZ) referenced in function _main

The simple sample below creates a similar error, if the definition of ~Client is missing. In your case althought the definition exists, the linker seems to not see it. When I get into this type of problem, I strip the code to its bare essentials and usually the problem becomes obvious.

class Client
{
public:
Client();
~Client();
};

Client::Client()
{
}

#ifdef MISSING
Client::~Client()
{
}
#endif
 
int main()
{
   Client c;
   return 0;
}
 
test2.obj : error LNK2019: unresolved external symbol "public: __thiscall Client::~Client(void)" (??1Client@@QAE@XZ) referenced in function _main

I don't understand, so the definition is there in my code? So what is the problem?

The code looks right but the linker is not seeing the definition, therefore the error. Another possible reason may be that client.cpp is not included in the visual studio project.

Compiler (C/C++) advanced setting -> Calling convention should be the same for all files in your VS project. __fastcall (/Gr) is preferable for "Release" builds.

Compiler (C/C++) advanced setting -> Calling convention should be the same for all files in your VS project. __fastcall (/Gr) is preferable for "Release" builds.

Sorry, what does that mean? lol I don't see any options like that in VS2008.

Check http://msdn.microsoft.com/en-us/library/fwkeyyhe(v=VS.90).aspx and look for /Gr /Gz or /Gd compiler options.

Thanks, it did turn out to be a compiler issue. I couldn't find out how to fix it so I reverted to a backup and added my code back in, which solved the problem.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.