all
i created a static lib project with VS 2010 sp1, and simply defined a class with a member function (code snippet):
.h:
namespace puphttp{
class CRequester
{
public:
void RequesterUpdate();
};
}
.cpp:
#include "StdAfx.h"
#include "Requester.h"
#include <iostream>
using namespace std;
namespace puphttp{
void CRequester::RequesterUpdate()
{
cout<<"updating";
}
}
at last i linked the lib file and tried to invoke the following code:
puphttp::CRequester c;
c.RequestUpdate();
the following link error occur as i compile:
error LNK2001: unresolved external symbol "public: void __cdecl puphttp::CRequester::RequestUpdate(void)" (?RequestUpdate#CRequest#puphttp##QEAAXXZ)
then i used dumpbin to check the actual function name in my lib, it's:
(?RequestUpdate#CRequest#puphttp##QAEXXZ)
so the difference is QEAAXXZ vs QAEXXZ, i didn't have time to get into name mangling rule yet, so any quick answer? really much appreciated.
Related
This is my eventhandler.h
#pragma once
#include <queue>
#include <Windows.h>
class EventHandler
{
public:
EventHandler()
{
}
~EventHandler()
{
}
static std::queue<MSG*> Events;
};
I've searched a lot to try and solve my problem and all the answers say to declare the static variable in a c++ file, which I've done
#include "EventHandler.h"
std::queue<MSG*> EventHandler::Events;
but I still get
Error LNK2001 unresolved external symbol "protected: static struct tagMSG * Entity::msg" (?msg#Entity##1PAUtagMSG##A)
and I can't figure out why. Have I missed something?
You also need to place your static in cpp file:
// EventHandler.cpp
std::queue<MSG*> EventHandler::Events;
I am trying to create a rather simple project in native c++ that calls a a managed dll.
this how my native c++ code looks:
// MyCppStud.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "MyStudWrapper\MyStudentWrapperWrapper.h"
int _tmain(int argc, _TCHAR* argv[])
{
char * path = "C:/Users/rami.schreiber/documents/visual studio 2013/Projects/TestProj/test.xml";
MyStudentWrapperWrapper* student = new MyStudentWrapperWrapper();
// student->GetStudent(path);
return 0;
}
and here are the .h and .cpp files for the managed dll (compiled with /clr)
//MyStudentWrapperWrapper.h
#pragma once
//#ifdef THISDLL_EXPORTS
#define THISDLL_API __declspec(dllexport)
/*#else
#define THISDLL_API __declspec(dllimport)
#endif*/
class MyStudentWrapper;
class THISDLL_API MyStudentWrapperWrapper
{
private:
MyStudentWrapper* _Impl;
public:
MyStudentWrapperWrapper();
MyStudentWrapperWrapper(MyStudentWrapper* student);
~MyStudentWrapperWrapper();
MyStudentWrapperWrapper* GetStudent(const char* path);
void SaveStudent(MyStudentWrapperWrapper* student, const char* path);
};
// MyStudentWrapperWrapper.cpp
#pragma once
#include "stdafx.h"
#include "MyStudWrapper.h"
#include "MyStudentWrapperWrapper.h"
MyStudentWrapperWrapper::MyStudentWrapperWrapper()
{
_Impl = new MyStudentWrapper;
}
when i build the solution i get a link error
1>MyCppStud.obj : error LNK2019: unresolved external symbol "public: __thiscall MyStudentWrapperWrapper::MyStudentWrapperWrapper(void)" (??0MyStudentWrapperWrapper##QAE#XZ) referenced in function _main
1>c:\users\...\documents\visual studio 2013\Projects\MyStudentProj\Debug\MyCppStud.exe : fatal error LNK1120: 1 unresolved externals
From what I understand I am not referencing the the .lib file correctly and therefor the linker does not recognize the c'tor for my wrapper class.
can someone please explain how to correctly reference the dll to my c++ project.
thank you very much!
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 9 years ago.
I'm working on own double linked list and everytime after adding object of class DoubleList in Evidence.cpp I get a LNK2019 error: Unresolved external symbol. I will be glad for every advice. Here are my codes:
StudentRecord.h
#pragma once
#include <string>
#include <iostream>
#include <algorithm>
#include "Student.h"
#include "DoubleList.h"
using namespace std;
using namespace SemestralWork;
class StudentRecord{
public:
DoubleList<Student> *List; //declared object (in StudentRecord.cpp is problem with that)
StudentRecord(void);
~StudentRecord(void);
Student &SearchStudent(const string &ID);
void addStudent(const Student &student, Student::Position position = Student::Position::LAST);
Student RemoveStudent(const string &ID);
void WriteAllStudents(void);
void Cancel(void);
};
StudentRecord.cpp (just part)
#include "StdAfx.h"
#include "StudentRecord.h"
using namespace SemestralWork;
StudentRecord::StudentRecord(void)
{
List = new DoubleList<Student>(); // <---- here is first LNK2019 error
}
Student &StudentRecord::SearchStudent(const string &ID){
Student * SearchedStudent;
Student * EmptyStudent = NULL;
//********** down here are next 4 LNK2019 errors. ************
for(DoubleList<Student>::iterator it = List->begin(); it != List->end(); ++it){
if(ID == List->AccessActual().getID()){
SearchedStudent = &List->AccessActual();
return *SearchedStudent;
}
} // 5 unresolved externals
return *EmptyStudent;
}
//...
DoubleList (just constructor)
template<typename T>
DoubleList<T>::DoubleList(void){
NumberOfElements = 0;
First= NULL;
Last= NULL;
Actual= NULL;
}
Student.h
#pragma once
#include <string>
using namespace std;
class Student
{
private:
string firstName, lastName, ID;
public:
Student(string, string, string);
~Student(void);
string getFirstName();
string getLastName();
string getID();
enum Position{ FIRST, LAST, ACTUAL, PREVIOUS, NEXT};
};
EDIT: Error message here:
Error 5 error LNK2019: unresolved external symbol "public: class Student & __thiscall SemestralWork::DoubleList::AccessActual(void)" (?AccessActual#?$DoubleList#VStudent###SemestralWork##QAEAAVStudent##XZ) referenced in function "public: class Student & __thiscall StudentRecord::SearchStudent(class std::basic_string,class std::allocator > const &)" (?SearchStudent#StudentRecord##QAEAAVStudent##ABV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
(one of five LNK errors)
So, you have a message. I'll break the message in several lines. The message should be read like this:
LNK2019: unresolved external symbol
"some function or variable that compiler saw nicely declared but the linker can't find the definition of"
(name of the missing symbol as linker sees it)
referenced in function
"some function where the missing function/variable is being used"
(name of the function as linker sees it)
In your case linker needs function DoubleList::AccessActual(void) in namespace SemestralWork. The function is declared somewhere, most likely in DoubleList.h. You probably need to add DoubleList.cpp file to the project. Maybe you forgot to define the function? In that case you have to write it.
Also, you really, really need to remove using namespace lines from header files. Really! Classes that exist in namespaces MUST be declared like this:
namespace SomeNamespace {
class SomeClass
{
void SomeFunction();
...
}
}
And SHOULD be defined like this in source file:
void SomeNamespace::SomeClass::SomeFunction()
{
...
}
In header files all stuff from any other namespaces, including std namespace, SHOULD be used with full name (std::string). In source files you MAY use using namespace std AFTER all #include directives. Some people disagree on this last one, but it's a matter of style.
can I just start by saying I appreciate you taking your time to go through my question and attempting to help. However I have already attempted the solution suggested on here and on here and they haven't worked for me.
This is my problem:
I am attempting to create a serial port class as a VS12 DLL project. I have a header file "SerialDll.h" which is included in my c++ source file "SerialDll.cpp". When I try to build the solution in visual studio 2012, i get the errors below:
Error 11 error LNK1120: 1 unresolved externals C:\Sprint 7\SerialDll\Debug\SerialDll.dll 1 1 SerialDll
Error 10 error LNK2001: unresolved external symbol "__declspec(dllimport) private: static void * MySerial::MySerialPort::serial_port_handle" (__imp_?serial_port_handle#MySerialPort#MySerial##0PAXA) C:\Sprint 7\SerialDll\SerialDll\SerialDll.obj SerialDll
When I try implementing John Zwinck's Solution, this is the error i get:
Error 2 error C2491: 'MySerial::MySerialPort::serial_port_handle' : definition of dllimport static data member not allowed c:\sprint 7\serialdll\serialdll\serialdll.cpp 16 1 SerialDll
This is the code in my header file:
#include <Windows.h>
#ifdef SERIAL_DLL_EXPORTS
#define SERIAL_DLL_API __declspec(dllexport)
#else
#define SERIAL_DLL_API __declspec(dllimport)
#endif
namespace MySerial
{
class MySerialPort
{
private:
static SERIAL_DLL_API HANDLE serial_port_handle;
public:
SERIAL_DLL_API MySerialPort();
SERIAL_DLL_API ~MySerialPort();
};
}
This is the code in my c++ source file, with John Zwinck's solution:
#include "stdafx.h"
#include "SerialDll.h"
#include <stdexcept>
#include <iostream>
using namespace std;
namespace MySerial
{
HANDLE MySerialPort::serial_port_handle;
MySerialPort::MySerialPort()
{
serial_port_handle = INVALID_HANDLE_VALUE;
}
MySerialPort::~MySerialPort()
{
if(serial_port_handle != INVALID_HANDLE_VALUE)
{
CloseHandle(serial_port_handle);
}
serial_port_handle = INVALID_HANDLE_VALUE;
}
}
Hope you guys can help me with a solution or at least refer me to a link with a working solution.
Cheers!
The answer is exactly the same as this answer to the previous question you linked:
https://stackoverflow.com/a/17902142/4323
That is, you have only declared, but not allocated storage for, your static member. You need to add this to your implementation file:
namespace MySerial
{
HANDLE MySerialPort::serial_port_handle;
}
If you are looking to export the class outside the DLL, then you need to use __declspec for the class, and not for each member function/variable. (See http://msdn.microsoft.com/en-us//library/a90k134d.aspx )
Your header file needs to look like :
namespace MySerial
{
class SERIAL_DLL_API MySerialPort
{
private:
static HANDLE serial_port_handle;
public:
MySerialPort();
~MySerialPort();
};
}
I have 2 static libraries from «vendor1» and «vendor2»:
vendor1.lib and vendor1.h;
vendor2.lib and vendor2.h.
In the file, vendor1.h. The following declaration is there:
double Min();
In the file, vendor2.h. The following declaration is there:
double Min();
In my client file:
include "vendor1.h"
include "vendor2.h"
double x = Min();
It by defaults calls vendor1.h. I tried introducing the namespace:
namespace vendor1 {
include "vendor1.h"
}
namespace vendor2 {
include "vendor2.h"
}
A call to the following function
double xx = vendor2::Min();
I get the following linker errors:
Client.cpp 1>Client.obj : error LNK2019: unresolved external symbol "double __cdecl vendor2::Min(void)" (?Min#vendor2##YANXZ) referenced
in function _wmain 1>c:\temp\Client\Debug\Client.exe : fatal error
LNK1120: 1 unresolved externals
How can I fix this without creating wrappers for each of the wrappers?
If you have two static libraries with conflicting names you won't be able to link your program statically! The static linker will just go and find the first symbol matching an undefined symbol and choose this. Wrapping the names into a namespace doesn't help: this changes the namespace being expected in the library. You just found why namespace are a good thing.
How to solve the problem? I'm not aware of an approach which is based on the C++ standard. Practically, you may be able to do something: create a dynamic library which forwards to your conflicting functions but puts the name into separate namespaces (or uses different names). The dynamic libraries are linked with individual static libraries, i.e. the conflict doesn't happen at this time. You will probably also need to avoid the underlying names being visible from the symbols in the shared library. The details on how this is done depend on the compiler and I don't know who to deal with MSVC++ for things like this.
How about wrapping the functions into different namespaces?
vendor1_wrapper.h:
namespace vendor1 {
double Min();
}
vendor1_wrapper.cpp:
#include "vendor1_wrapper.h"
#include "vendor1.h"
namespace vendor1 {
double Min()
{
return Min();
}
}
vendor2_wrapper.h:
namespace vendor2 {
double Min();
}
vendor2_wrapper.cpp:
#include "vendor2_wrapper.h"
#include "vendor2.h"
namespace vendor2 {
double Min()
{
return Min();
}
}
Now you can use the functions using namespaces (your client file):
#include "vendor1_wrapper.h"
#include "vendor2_wrapper.h"
...
vendor1::Min();
vendor2::Min();