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.
Related
I have a static method called getSingleton() in a class called Renderer, which I use as a macro like this:
Renderer.h
#define g_Renderer Renderer::getSingleton()
class Renderer {
private:
Renderer();
static Renderer renderer;
public:
Renderer getSingleton();
};
Renderer.cpp
#include "Renderer.h"
Renderer::Renderer() {}
Renderer Renderer::getSingleton() {
#ifndef CREATED_RENDERER
#define CREATED_RENDERER;
renderer = Renderer();
#endif // !CREATED_RENDERER
return renderer;
}
I access the method in main:
Main.cpp
#include "Renderer.h"
int main(){
return 0;
}
But Visual Studio gives me this error:
Main.obj : error LNK2019: unresolved external symbol "public: static class Renderer __cdecl Renderer::getSingleton(void)" (?getSingleton#Renderer##SA?AV1#XZ) referenced in function main
Why is this? Thanks in advance!
Your getRenderer() method is setup all wrong for what you are trying to do.
For one thing, it is not static.
For another, the static variable is only being declared, not defined anywhere, which is why the linker is complaining. You would need to add this line to Renderer.cpp to actually instantiate the variable:
Renderer Renderer::renderer;
Also, getRenderer() is returning a new Renderer object each time it is called, which is useless for a singleton. The #ifdef is also useless at runtime.
Try something more like this instead:
Renderer.h
#ifndef Renderer_H
#define Renderer_H
#define g_Renderer Renderer::getSingleton()
class Renderer {
private:
Renderer();
public:
static Renderer& getSingleton();
};
#endif
Renderer.cpp
#include "Renderer.h"
Renderer::Renderer() {}
Renderer& Renderer::getSingleton() {
static Renderer instance;
return instance;
}
Main.cpp
#include "Renderer.h"
int main(){
// use g_Renderer as needed...
return 0;
}
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 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.
I'm trying to implement a State Pattern in C++, but have problems with the circular dependency. I have read other related material here - unfortunately it didn't help me. I don't have a lot of experience with C++, so bear with me.
The following code is developed on a Ubuntu 10.10 machine in Eclipse Helios CDT:
ConcreteSystem.h
#ifndef CONCRETESYSTEM_H_
#define CONCRETESYSTEM_H_
class SystemState;
class ConcreteSystem {
public:
ConcreteSystem();
void SelfTestFailed();
void Restart();
private:
friend class SystemState;
SystemState *currentState;
void ChangeState(SystemState *state);
};
#endif /* CONCRETESYSTEM_H_ */
ConcreteSystem.cpp
#include "ConcreteSystem.h"
#include "SystemState.h"
ConcreteSystem::ConcreteSystem() {
currentState = SelfTest::GetInstance();
}
void ConcreteSystem::SelfTestFailed() {
currentState->SelfTestFailed(this);
}
void ConcreteSystem::Restart() {
currentState->Restart(this);
}
void ConcreteSystem::ChangeState(SystemState *state){
currentState = state;
}
SystemState.h
#ifndef SYSTEMSTATE_H_
#define SYSTEMSTATE_H_
class ConcreteSystem;
class SystemState {
public:
virtual void Restart(ConcreteSystem *cs);
virtual void SelfTestFailed(ConcreteSystem *cs);
protected:
virtual void ChangeState(ConcreteSystem *cs, SystemState *state);
};
#endif /* SYSTEMSTATE_H_ */
SystemState.cpp
#include "SystemState.h"
#include "ConcreteSystem.h"
void SystemState::Restart(ConcreteSystem *cs) {
}
void SystemState::SelfTestFailed(ConcreteSystem *cs) {
}
void SystemState::ChangeState(ConcreteSystem *cs, SystemState *state) {
cs->ChangeState(state);
}
SelfTest.h
#ifndef SELFTEST_H_
#define SELFTEST_H_
#include "SystemState.h"
class SelfTest : public SystemState {
public:
SelfTest();
void SelfTestFailed(ConcreteSystem* cs);
static SystemState* GetInstance();
private:
static SystemState* instance;
};
#endif /* SELFTEST_H_ */
SelfTest.cpp
#include "SelfTest.h"
#include "Failure.h"
SystemState* SelfTest::instance = 0;
SelfTest::SelfTest() {
}
void SelfTest::SelfTestFailed(ConcreteSystem *cs) {
ChangeState(cs, Failure::GetInstance());
}
SystemState* SelfTest::GetInstance() {
if (instance == 0) {
instance = new SelfTest();
}
return instance;
}
Failure.h
#ifndef FAILURE_H_
#define FAILURE_H_
#include "SystemState.h"
class SelfTest;
class Failure : public SystemState {
public:
Failure();
void Restart(ConcreteSystem* t);
static SystemState* GetInstance();
private:
static SystemState* instance;
};
#endif /* FAILURE_H_ */
Failure.cpp
#include "Failure.h"
#include "SelfTest.h"
SystemState* Failure::instance = 0;
Failure::Failure() {
}
void Failure::Restart(ConcreteSystem* t) {
ChangeState(t, SelfTest::GetInstance());
}
SystemState* Failure::GetInstance() {
if (instance == 0) {
instance = new Failure();
}
return instance;
}
I have problem with the includes, which gives me some weird compiler errors. Anyone with a good solution to this problem?
From the looks of the code you've posted, you'll have classes being redefined. Looking at your Failure.cpp file, you have:
#include "Failure.h"
#include "SelfTest.h"
Which will include both of those files, and each of those files include the SystemState.h file. Since the SystemState.h file is included more than once, it tries to redefine the SystemState class. At the top of each of your header files, you should do something like this:
// SystemState.h
#ifndef SystemState_h
#define SystemState_h
.. class definition ..
#endif // close the if statement from above.
As an aside on the design, I think it's bad form for the states to know about each other - use your ConcreteSystem as a state controller and then base the state on the return value of the last state operation.
Also, if you're relatively inexperienced with C++, I would recommend looking at this as a great source of learning material (in addition to StackOverflow, of course!).
My code is stored in a main.cpp file which contains the void main() function, and a class MyClass which I now want to split to another file. IDE is Microsoft Visual Studio 2008 Professional.
myclass.h
#include <tchar.h>
class MyClass {
public:
static bool MyFunction (TCHAR* someStringArgument);
};
myclass.cpp
#include <tchar.h>
class MyClass {
private:
static bool someProperty;
static void doSomeOneTimeCode () {
if (!someProperty) {
/* do something */
someProperty = true;
}
}
public:
static bool MyFunction (TCHAR* someStringArgument) {
doSomeOneTimeCode();
/* do something */
return true;
}
};
bool MyClass::someProperty = false;
main.cpp
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include "myclass.h"
void main () {
if (MyClass::MyFunction(TEXT("myString"))) {
_tprintf(TEXT("Yay\n"));
}
}
However, when I try to run it, I get two linker errors.
LNK2019: unresolved external symbol ... (mentions MyClass::MyFunction)
LNK1120: 1 unresolved externals
What can I do to prevent these linker errors?
You declared two classes here. One of them is in myclass.h and the other is in myclass.cpp. Try the following instead:
myclass.h
#ifndef myclass_h_included
#define myclass_h_included
#include <tchar.h>
class MyClass {
private:
static bool someProperty;
static void doSomeOneTimeCode ();
public:
static bool MyFunction (TCHAR* someStringArgument);
};
#endif //!myclass_h_included
myclass.cpp
#include "myclass.h"
/*static*/ bool MyClass::someProperty = false;
void
MyClass::doSomeOneTimeCode() {
//...
}
bool
MyClass::MyFunction(TCHAR* someStringArgument) {
//...
}
Your main.cpp can stay the same. I would pay attention to UncleBens reply as well. One time initialization code should be hidden if at all possible.
Yo can't split a class definition in parts. It must be defined as a whole in one place. If you want to just have some methods of the class defined create a interface class that the MyClass class will later inherit. You should put the class' definition in a header file (myclass.h) and it's implementation in a cpp file (myclass.cpp). That way you can include the "myclass.h" in your main cpp file and use the class in your main function (which should be int main() or int main( int argc, char *argv[] )).
Strange that you didn't get a compiler error, as you are redefining MyClass.
Definitions (implementations) go into the cpp, and they are defined like this:
#include "myclass.h"
//helper functions, particularly if static, don't need to be in the class
//unnamed namespace means this stuff is available only for this source file
namespace
{
bool someProperty;
void doSomeOneTimeCode () {
if (!someProperty) {
/* do something */
someProperty = true;
}
}
}
bool MyClass::MyFunction (TCHAR* someStringArgument) {
doSomeOneTimeCode();
/* do something */
return true;
}