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;
}
//*******************************************************

Dani AI

Generated

The unresolved externals for the Client constructor, destructor and Connect indicate the linker never saw the compiled definitions. That can be caused by the implementation file not being part of the build, by mismatched signatures/name‑mangling (calling conventions, namespace or preprocessor differences), or by corrupted project settings. The suggestions already offered by (Client.cpp not compiled) and (calling convention mismatch) are all common and are consistent with the final post by where reverting the project fixed the issue.

Common checks and quick diagnostics:

  • Confirm Client.cpp is actually compiled for the active configuration and platform. In Solution Explorer inspect the file properties: "Excluded From Build" must be No and "Item Type" should be C/C++ compiler.
  • Verify the object file is produced (look in the intermediate/Debug or Release folder for Client.obj). If it is not present the file either failed to compile or was excluded.
  • Ensure the implementation exactly matches the header (same class name, namespace, qualifiers and no conditional compilation that changes signatures). Watch for preprocessor macros that alter the declaration between client/server builds.
  • Check project-wide compiler options: calling convention and runtime-library must be consistent across all .cpp files. Also confirm precompiled-header rules (stdafx.h first include) so the file actually compiles.
  • Inspect the linker inputs or build log (enable detailed/diagnostic build output) to confirm whether Client.obj is passed to the linker.

If the above checks still show no problem, recreate the project or remove and re-add the source file to the project (project-file corruption can silently exclude files). Creating a minimal repro (class with ctor/dtor in a tiny project) quickly shows whether the toolchain or project settings are at fault.

Recommended Answers

All 11 Replies

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.