unresolved external symbol in C++ DLL project - c++

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();
};
}

Related

Static variable link error in MSVC even though it is created in the cpp file

I am working on a cross-platform (Linux & Windows) library. One of my class has a static member defined in the header. And I created it in a CPP file like
namespace raisim {
std::function<void()> RaiSimMsg::fatalCallback_ = []() { exit(1); };
}
The header file
#ifndef RAISIM_MESSAGE_LOGGER_HPP
#define RAISIM_MESSAGE_LOGGER_HPP
#include <chrono>
...
namespace raisim {
class RaiSimMsg {
public:
...
void stream(const char *file, const int line, std::stringstream &msg, int severity) {
if (severity == RSEVERITY_FATAL)
fatalCallback_();
}
private:
static std::function<void()> fatalCallback_;
};
}
#endif //RAISIM_MESSAGE_LOGGER_HPP
This works perfectly with GCC and Clang in Linux. But MSVC is giving a link error. Does MSVC have its own rules for static members??
Full error log
1>anymal.obj : error LNK2001: unresolved external symbol "private: static class std::function<void __cdecl(void)> raisim::RaiSimMsg::fatalCallback_" (?fatalCallback_#RaiSimMsg#raisim##0V?$function#$$A6AXXZ#std##A)
1>C:\Users\ultrafrog\source\repos\raisim\build\benchmark\Debug\speed_test_anymal.exe : fatal error LNK1120: 1 unresolved externals
1>Done building project "speed_test_anymal.vcxproj" -- FAILED.
Jack Dingler's answer here
https://www.codeproject.com/Questions/585271/Aplusstaticplusmemberplusvariableplusexportpluserr
worked. So the issue is that the Windows linker needs to know that if it has to import or export the symbol. So we have to declare __declspec(dllexport) when we export (when we build the library) and __declspec(dllimport) for using it. We can switch that using a compilation flag. I am not sure why they designed the linker like this but anyway it works now.

Unresolved external symbol "protected static struct" error despite being defined in a .cpp file

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;

C++ unresovled external symbol link error related with name mangling?

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.

Link error when referencing managed dll to native c++

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!

unresolved external symbol visual studio 2010 error

i've implemented with visual studio 2010 professional a solution containing 2 projects; the first called OptDll consist of a dynamic library with a method i want to export, while the second is a exe project, called prova, in order to try the dll.
I've included the correct references and all work fine until i decided to insert in OptDll project a new class (GlobalOutput) in order to create the output parameters i want. When i build the project OptDll no error occurs but when i build the whole solution i get these errors in the prova project:
Error 59 error LNK2019: unresolved external symbol "public: __thiscall GlobalOutput::~GlobalOutput(void)" (??1GlobalOutput##QAE#XZ) referenced in function _main C:\Users\ANTONIO\Desktop\optDll\prova\prova.obj
Error 60 error LNK2019: unresolved external symbol "public: __thiscall GlobalOutput::GlobalOutput(void)" (??0GlobalOutput##QAE#XZ) referenced in function _main C:\Users\ANTONIO\Desktop\optDll\prova\prova.obj
Error 61 error LNK1120: 2 unresolved externals C:\Users\ANTONIO\Desktop\optDll\Debug\prova.exe 1
I read it could be a problem with the class constructor/destructor but i don't fix it.
Below the code of interest.
OptFunDll.h
#ifdef OPTFUNDLL_EXPORTS
#define OPTFUNDLL_API __declspec(dllexport)
#else
#define OPTFUNDLL_API __declspec(dllimport)
#endif
//#include "tool_library.h"
#include "GlobalOutput.h"
namespace optFun
{
// This class is exported from the optFunDll.dll
class myoptFun
{
public:
// funzione che implementa il modulo di ottimizzazione
class OPTFUNDLL_API GlobalOutput;
static OPTFUNDLL_API void scheduling(const char*,const char*,const char*,const char*,GlobalOutput&);
};
}
OptFunDll.cpp
#include "stdafx.h"
#include "optFunDll.h"
#include <stdexcept>
using namespace std;
::Random Particle::_rnd;
::Random ParticleSwarm::_rnd;
namespace optFun
{
void myoptFun::scheduling(const char *pRicette,const char *pWarehouse,const char *pFarmacia,const char *pShaker,GlobalOutput& total){
//here some code...
//class definition
total.CreateDataPrescription(final_list);
total.time=time_output;
GlobalOutput.h
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxadv.h>
#include <afxdisp.h> // MFC Automation classes
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
#include "GlobalInfo.h"
#include "tool_library.h"
struct DataPrescription{
EDrug NameDrug;
double Dosage;
EContainerType DestType;
ELiquid IdDest;
double CapacityDest;
double Priority;
bool ScaricoShaker;
DataPrescription(){
NameDrug=EDrug_NoDrug;
Dosage=0.0;
DestType= EContainerType_Tot;
IdDest=ELiquid_NoLiquid;
CapacityDest=0.0;
Priority=0.0;
ScaricoShaker=true;
}
DataPrescription(EDrug name,double dos,EContainerType dest,ELiquid ID,double cap_dest,double p,bool _ScaricoShaker){
NameDrug=name;
Dosage=dos;
DestType=dest;
IdDest=ID;
CapacityDest=cap_dest;
Priority=p;
ScaricoShaker=_ScaricoShaker;
}
};
class GlobalOutput{
public:
CArray<DataPrescription> OptList;
time_info time;
GlobalOutput();
~GlobalOutput();
void CreateDataPrescription(vector<ricetta>&);
};
#endif
GlobalOutput.cpp
#include "stdafx.h"
#include "GlobalOutput.h"
GlobalOutput::GlobalOutput(){
time.total_makespan=0;
}
GlobalOutput::~GlobalOutput(){
}
void GlobalOutput::CreateDataPrescription(vector<ricetta>& list){
//DataPrescription tmp;
for(unsigned int i=0;i<list.size();i++){
DataPrescription tmp(list[i].getID(),list[i].getdosage(),list[i].get_destination(),list[i].get_DestType(),list[i].get_CapacityDest(),list[i].getPriority(),list[i].processing_info.scarico_shaker);
this->OptList.Add(tmp);
}
}
and Finally the main of prova project:
#include "stdafx.h"
#include "optFunDll.h"
#include <iostream>
//#include "C:\Users\ANTONIO\Desktop\optDll\optDll\tool_library.h"
using namespace std;
int main()
{
const char *pRicette;
pRicette=new char(NULL);
const char *pWarehouse;
pWarehouse=new char(NULL);
const char *pFarmacia;
pFarmacia=new char(NULL);
const char *pShaker;
pShaker=new char(NULL);
optFun::myoptFun::GlobalOutput total;
optFun::myoptFun::scheduling(pRicette,pWarehouse,pFarmacia,pShaker,total);
return 0;
}
Thanks for your help.
Please let me know if you want more info.
if I comment the code lines under class definition in OptDll.cpp i get these errors:
Error 5 error C2079: 'total' uses undefined class 'optFun::myoptFun::GlobalOutput' c:\users\antonio\desktop\optdll\prova\prova.cpp 23
Error 6 error C2664: 'optFun::myoptFun::scheduling' : cannot convert parameter 5 from 'int' to 'optFun::myoptFun::GlobalOutput &' c:\users\antonio\desktop\optdll\prova\prova.cpp 24
instead if i uncomment the definition of total i obtain also:
9 IntelliSense: incomplete type is not allowed c:\users\antonio\desktop\optdll\optdll\optfundll.cpp 131
Thanks for you availability, I'm new on c++ programming.
You are not actually exporting your class GlobalOutput.
You need to have:
class OPTFUNDLL_API GlobalOutput