I'm programing in visual studio c++. I have Field, IField, Map and IMap in DLL. I create interfaces IField and IMap to have access to Field and Map in unit test. When i run this simple code in unit test:
IMap m;
IField f(3, 4);
m.shoot(f);
I have following error:
LNK2019 unresolved external symbol "public: virtual __thiscall
Field::~Field(void)" (??1Field##UAE#XZ) referenced in function
"public: virtual void * __thiscall Field::`scalar deleting
destructor'(unsigned int)" (??_GField##UAEPAXI#Z) TestShipGameDll
#pragma once
class Field
{
public:
Field(int x, int y) : x(x), y(y) {}
virtual ~Field() {}
protected:
int x;
int y;
};
.
#ifdef IFIELD_EXPORTS
#define IFIELD_API __declspec(dllexport)
#else
#define IFIELD_API __declspec(dllimport)
#endif
class IField :
public Field
{
public:
IFIELD_API IField(int x, int y) :Field(x, y)
IFIELD_API virtual ~IField() {}
};
.
class Map
{
public:
Map();
virtual ~Map();
void shoot(Field field)
{
//here is empty body of function
}
};
.
#ifdef IMAP_EXPORTS
#define IMAP_API __declspec(dllexport)
#else
#define IMAP_API __declspec(dllimport)
#endif
class IMap :
public Map
{
public:
IMAP_API IMap() {}
IMAP_API virtual ~IMap() {}
IMAP_API void shoot(Field field)
{
Map::shoot(field);
}
};
.
It's weird. It looks like it was missing copying constructor but I do not have any pointers in Field. Only automatic variables x and y. Do you have any tips to resolve this fancy error?
You have to export the whole class with IFIELD_API - otherwise the compiler-generated functions are not visible outside the shared library and you will get linker errors.
Related
in a MSVC dll project, i tried to create a dll containing a base class
//header file
class MATHLIBRARY_API Shape {
protected:
int width, height;
public:
Shape(int, int);
int area(void) { return -1; };
};
it's compiled successfully, but when adding a virtual specifier to the function
class MATHLIBRARY_API Shape {
protected:
int width, height;
public:
Shape(int, int);
virtual int area(void) { return -1; };
};
the compiler showed error msg
Error LNK2019 unresolved external symbol `__declspec(dllimport) const Shape::`vftable'" (__imp_??_7Shape##6B#) referenced in function "public: __thiscall Shape::Shape(int,int)" (??0Shape##QAE#HH#Z) Dll3 c:\Users\langj\source\repos\Dll3\Dll3\Dll3.obj 1
where could be the problem?
I've got a problem using 3rd party .dll library:
That library has some class with methods I need to use in my compiled .dll via JNI from my Java app.
I'm trying to declare something like that :
#ifdef SERVER_EXPORTS
#define SERVER_API __declspec(dllexport)
#else
#define SERVER_API __declspec(dllimport)
#endif
namespace MYDLLNAMESPACE
{
class SERVER_API IServer
{
public:
int NFun(int func);
};
class SERVER_API ServerClass : public IServer {
public:
ServerClass();
int NFun(int func) {
return MYDLLNAMESPACE::ServerClass::NFun(func);
}
};
}
Ant then use it in code like :
IServer *Myserv = new Server();
int a = Myserv->NFun(5007);
return a;
but it goes to the error "error LNK2019: unresolved external symbol "__declspec(dllimport) public: int __thiscall MYDLLNAMESPACE::IServer:"
I need to do something like:
Iserver myServer = new Server();
int result = myServer.do_smth();
return result;
where Server is MYDLL.dll --> namespace MYDLLNAMESPACE --> class Server
Is there any ways how to do it?
P.S. I haven't any .lib of .h files of 3rd party .dll
EDIT:
Now I've got Server.h file :
namespace NS {
class __declspec(dllexport) ServerClass
{
public:
ServerClass() {
}
const char* GParam(const char* key);
const char* SParam(const char* key, const char* value);
};
}
And my Impl.cpp file, where I tryin' to instantiate ServerClass and use its method 'GParam' like this:
ServerClass *serv = new ServerClass();
const char* str = serv->GParam("LastErrorTxt");
but it goes to StackOverFlowException, seems like serv->GParam("LastErrorTxt") is executing itself instead of dll class implementation
Problem is solved by using com4j:
http://com4j.kohsuke.org/
I have an DLL in which I have added a second class which has only static members, but when I try to build this I got linker error:
Error 14 error LNK2001: unresolved external symbol "__declspec(dllimport) private: static double BubblyCore::BubblyTime::delta" (__imp_?delta#BubblyTime#BubblyCore##0NA) D:\Projekty\bubbly-engine\BCore\BCore.obj BCore
And same for second member.
Here is my header:
#ifdef BCOREDLL_EXPORTS
#define BCOREDLL_API __declspec(dllexport)
#else
#define BCOREDLL_API __declspec(dllimport)
#endif
#include <..\BDisplay.h>
#include <ctime>
#include <chrono>
typedef std::chrono::time_point<std::chrono::system_clock, std::chrono::system_clock::duration> BChronoTime;
namespace BubblyCore
{
// This class is exported from the BCOREDll.dll
class BCOREDLL_API MainBubble
{
public:
private:
BDisplay* pbDisplay;
bool isRunning;
public:
MainBubble(BDisplay* pbDisplay);
void Start();
void Stop();
private:
void Run();
void Render();
void CleanUp();
};
class BCOREDLL_API BubblyTime
{
public:
static BChronoTime bStartTime;
private:
static double delta;
public:
static long getTime();
static double getDelta();
static void setDelta(double sDelta);
};
}
I am talking specific about BubblyTime. The first one is Ok so far.
Inside one of your .cpp files, add the following lines :
double BubblyCore::BubblyTime::delta = 0.0;
Declaring static variables in a header file won't be sufficient. You need to declare their real instances in some .cpp files.
I have the following header file containing a class and some variables
extern bool akwizycja_w_toku;
extern LPCTSTR pFileName;
extern int numer_akwizycji;
class Akwizycja : public TThread
{
public:
__fastcall Akwizycja(bool CreateSuspended);
void __fastcall Akwizycja::UpdateLabels();
Akwizycja::Akwizycja() {}
};
(just a sample, there is more but it doesn't matter)
furthermore I've got the main project
#include "Akwizycja.h"
void __fastcall Akwizycja::UpdateLabels()
{
Form1->Label12->Caption=FloatToStrF(dRate,ffFixed,8,4);
Form1->Label13->Caption=FloatToStrF(ActualRate,ffFixed,8,3);
Form1->Label14->Caption=FloatToStrF(EffectiveRate,ffFixed,8,3);
Form1->Label15->Caption=pow(2,Clock_Divider);
}
where arguments like dRate or ffFixed are some of the extern variables.
The problem starts when I want to use some of the functions
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Akwizycja* new_object = new Akwizycja;
}
I get [ILINK32 Error] Error: Unresolved external '_dRate' referenced from D:\DF\DEBUG\WIN32\RECEIVER.OBJ
for all of the variables used.
Suppose it's some path-setting issue, but all of them are added. Many thanks for any piece of advice.
I have this template smart pointer class in a dll.
sp.h
---------
#ifdef VLIB_EXPORTS
#define VLIB_API __declspec(dllexport)
#else
#define VLIB_API __declspec(dllimport)
#endif
template < typename T > class VLIB_API SP
{
protected:
T* m_pData;
long* m_pRefCounter;
public:
SP(void);
{
m_pData = NULL;
m_pRefCounter = NULL;
}
...
...
};
ImagePtr.h
---------------
class VLIB_API CVImagePtr
{
....
}
MainLib.h
-------------
#include sp.h
#include ImagePtr.h
typedef SP<CVBlob> CVBlobPtr;
class VLIB_API CVLib
{
public:
virtual CVBlobPtr CreateBlob() = 0;
virtual CVImagePtr CreateImg() = 0;
};
When I try to use this class in another project (CVMLib), the compiler will complain this:
error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall SP::~SP(void)"
but no problem for CVImagePtr.
class VMLIB_API CVMLib : public CVLib
{
public:
virtual CVBlobPtr CreateBlob();
virtual CVImagePtr CreateImg();
};
It seems there's a problem when the class is a template. If so, how do I export a template class?
Can somebody help me resolve this? Thank you!
As suspected, I'm not exporting the template class properly. This is what I did:
MainLib.h
#include sp.h
#include ImagePtr.h
#ifdef VLIB_EXPORTS
#define VLIB_API __declspec(dllexport)
#define EXPIMP_TEMPLATE
#else
#define VLIB_API __declspec(dllimport)
#define EXPIMP_TEMPLATE extern
#endif
EXPIMP_TEMPLATE template class VLIB_API SP<CVBlob>;
typedef SP<CVBlob> CVBlobPtr;
class VLIB_API CVLib
{
public:
virtual CVBlobPtr CreateBlob() = 0;
virtual CVImagePtr CreateImg() = 0;
};
You can find more information here:
http://support.microsoft.com/kb/168958
You need to mark the class with extern "C" in order to have the non mangled name on the implementation of the class as well as the header.
Have a look at this canonical answer as to why.