I'm tring to expose a static variable. I have tried doing this as both just a public static, and using access functions, but when I use the command Stage::SetFramework( this ); in my Framework class, or even if I make systemFramework public and use Stage::systemFramework = this, I get:
framework.obj||error LNK2001: unresolved external symbol "public: static class Framework * Stage::systemFramework" (?systemFramework#Stage##2PAVFramework##A)|
I'm not sure why this isn't working. I'm obviously missing something Can anyone help please?
#pragma once
#include "event.h"
#ifndef Framework
class Framework;
#endif // Framework
class Stage
{
protected:
static Framework* systemFramework;
public:
// static Framework* systemFramework;
// Stage control
virtual void Begin() = 0;
virtual void Pause() = 0;
virtual void Resume() = 0;
virtual void Finish() = 0;
virtual void Event(FwEvent *e) = 0;
virtual void Update() = 0;
virtual void Render() = 0;
static void SetFramework( Framework* FrameworkObject )
{
systemFramework = FrameworkObject;
};
/*
static Framework* GetFramework()
{
return systemFramework;
};
*/
};
Thanks
Listing static class data members in a class only declares them. They must still be defined somewhere. Put this definition into one .cpp file:
Framework *Stage::systemFramework;
That's because you need a FrameWork* Stage::systemFramework; somewhere too (in a .cpp file, typically). This "places" your variable you may, for example for caching reasons, have it next to some othver variables - so the compiler won't just throw it anywhere, so the declaration inside the class definition is just that, a declaration that "there will be one of these variable somewhere". [Or in an embedded system, there may be some part of memory that is backed up by battery power and another part of memory that isn't, and again, where you "place" the variable will matter in this case].
Of course, the public, private or protected inside the class will still determine which parts of the code can access the variable.
Related
First i will start with the reason i need name mangling on runtime.
I need to create a bridge between dll and its wrapper
namespace Wrapper
{
class __declspec(dllexport) Token
{
public:
virtual void release() {}
};
}
class __declspec(dllexport) Token
{
public:
virtual void release(){}
};
The idea is to use dumpin to generate all the mangled names of the dll holding class token and than demangled them.
?release#Token##UAEXXZ --> void Token::release(void)
after that i want to convert is to match the Wrapper so i will need to change the function name
void Token::release(void) --> void Wrapper::Token::release(void)
and then i need to mangle it again so i can create a def file that direct the old function to the new one.
?release#Token##UAEXXZ = ?release#Token#Wrapper##UAEXXZ
all this process needs to be on run time.
First and the easiest solution is to find a function that mangle strings but i couldn't find any...
any other solution?
The Clang compiler is ABI-compatible with MSVC, including name mangling.
The underlying infrastructure is part of the LLVM project, and I found llvm-undname which demangles MSVC names. Perhaps you can rework it to add the Wrapper:: namespace to symbols and re-mangle.
You can find inspiration about mangling names in this test code.
If you are allowed to change the DLL, I'd usually use a different approach, by exporting extern "C" getter function (that does not mangle thus doesn't need demangling) and using virtual interface to access the class (note that the virtual interface doesn't need to be dllexported then). Your Token interface seems to be virtual anyway.
Something along those lines (not tested, just to show the idea):
DLL access header:
class Token // notice no dllexport!
{
protected:
// should not be used to delete directly (DLL vs EXE heap issues)
virtual ~Token() {}
virtual void destroyImpl() = 0; // pure virtual
public:
static inline void destroy(Token* token) {
// need to check for NULL otherwise virtual call would segfault
if (token) token->destroyImpl();
}
virtual void doSomething() = 0; // pure virtual
};
extern "C" __declspec(dllexport) Token * createToken();
DLL implementation:
class TokenImpl: public Token
{
public:
virtual void destroyImpl() {
delete this;
}
virtual void doSomething() {
// implement here
}
};
extern "C" __declspec(dllexport) Token * createToken()
{
return new TokenImpl;
}
Usage:
// ideally wrap in RAII to be sure to always release
// (e.g. can use std::shared_ptr with custom deleter)
Token * token = createToken();
// use the token
token->doSomething();
// destroy
Token::destroy(token);
With shared::ptr (can also create a typedef/static inline convenience creator function in the Token interface):
std::shared_ptr<Token> token(createToken(),
// Use the custom destroy function
&Token::destroy);
token->doSomething()
// token->destroy() called automatically when last shared ptr reference removed
This way you only need to export the extern-C creator function (and the release function, if not part of the interface), which will then not be mangled thus easy to use via the runtime loading.
I have a QT library and I want to import it in another project.
Now, since I want that, even when I modify the library, the other project does not need to be compiled again, I started using QLibrary.
But... I can't import a class. Or better, I can import the class, but I can't access its methods.
This is the example I made.
This is the class declaration:
class TESTDLL_LIBSHARED_EXPORT TestDLL_lib
{
public:
TestDLL_lib();
int a;
int b;
int c;
int getValues();
};
and this the implementation:
#include "testdll_lib.h"
TestDLL_lib::TestDLL_lib()
{
a = 10;
b = 20;
c = 30;
}
int TestDLL_lib::getValues()
{
return a+b+c;
}
extern "C" TESTDLL_LIBSHARED_EXPORT TestDLL_lib* create_TestDLL_lib()
{
return new TestDLL_lib();
}
while this is the main file, in the other project:
#include <testdll_lib.h>
#include <QDebug>
#include <QLibrary>
int main(int argc, char *argv[])
{
QLibrary library("TestDLL_lib");
if (library.load())
{
typedef TestDLL_lib* (*create_TestDLL_lib_fun)();
create_TestDLL_lib_fun create_TestDLL_lib = (create_TestDLL_lib_fun)library.resolve("create_TestDLL_lib");
if (create_TestDLL_lib)
{
TestDLL_lib *myClassInstance = create_TestDLL_lib();
if (myClassInstance)
{
//qDebug() << QString::number(myClassInstance->getValues());
qDebug() << QString::number(myClassInstance->a) + " " + QString::number(myClassInstance->b) + " " + QString::number(myClassInstance->c);
}
}
library.unload();
}
}
Now, I can access all the data values (a, b, c) of the object myClassInstance (and, if i change them in the DLL, they also get changed in the program without a rebuild) but I can't call myClassInstance->getValues() because I get
main.obj:-1: error: LNK2001: unresolved external symbol "__declspec(dllimport) public: int __thiscall TestDLL_lib::getValues(void)" (__imp_?getValues#TestDLL_lib##QAEHXZ)
How can I solve this? Is it possible to call methods from imported classes?
Thank you..
You cannot call methods on classes imported at runtime. This is because the compiler links these calls at compile-time and not at run-time (which it cannot do). A way out is provided by our good ol' friend, the vtable:
You can, call virtual methods on classes implementing an interface (the interface is not "imported" at runtime). That means to define a class defining the interface using virtual (possibly pure virtual) methods. TestDLL_lib would then inherit that interface, implementing the methods. You would refer to the TestDLL_lib instance via that interface and call methods trough that interface, effectively calling them trough the vtable of the interface, which is "superseded" by TestDLL_libs vtable.
Don't forget to make your d'tor virtual and to add a virtual dtor to the interface. If you don't do that you cannot safely delete instance trough the interface pointer.
I might also explain why you can access members, but not call functions on "imported" classes. The members are accessed by memory location, and the memory location is solely defined by the compiler. Thus the compiler generates the code to access members without ever referring to any of the classes' symbols (methods and so on). This in turns leads to no linkage dependency. Note however that you would need to recompile both the DLL and the application using the DLL if you change the class, e.g. adding or removing a member, since that changes the memory layout.
class TestInterface
{
public:
virtual ~TestInterface()
{
}
virtual int getValues() = 0;
}
class TESTDLL_LIBSHARED_EXPORT TestDLL_lib : public TestInterface
{
public:
TestDLL_lib();
virtual ~TestDLL_lib();
int a;
int b;
int c;
int getValues() override; // MSVC may not support "override"
};
// return pointer to interface!
// TestDLL_lib can and should be completely hidden from the application
extern "C" TESTDLL_LIBSHARED_EXPORT TestInterface *create_TestDLL_lib()
{
return new TestDLL_lib();
}
I am currently working on a project that uses a DLL and an application that uses the DLL. The DLL is exported as an abstract base class header and a concrete implementation derived from the abstract base, as usual:
---- TaskInterface.h ----
class Task {
public:
virtual int func1(void) = 0;
virtual int func2(void) = 0;
};
extern "C" __declspec(dllexport) Task * APIENTRY newTask();
--- Task.h ---
class TaskImpl : public Task
{
public:
virtual int func1(void);
virtual int func2(void):
};
Task * APIENTRY newTask()
{
return static_cast<Task*>( new TaskImpl );
}
--- Task.cpp ---
int TaskImpl::func1(void)
{
// ...
}
int TaskImpl::func2(void)
{
// ...
}
This works so far as intended, the application includes "AbstractTask.h" and then calls the respective function defined by class TaskImpl:
--- TheApplication.cpp ---
Task aTask = newTask();
aTask->func1();
aTask->func2();
// ...
However, now the Application discovers that what the default implementation in class TaskImpl does is not enough and therfore defines within its own scope a new derived class, like so:
--- AppImpl.h ---
#include "TaskInterface.h"
class AppImpl : public Task
{
int func1(void) = { /* new stuff */ }
int func2(void) = { /* new stuff */ }
};
and then defines in TheApplication.cpp:
--- TheApplication.cpp ---
#include "AppImpl.h"
ApplImp * aNewTask = static_cast<Task*>(newTask());
aNewTask->func1();
aNewTask->func2();
In what context do you think func1() and func2() are called? Correct: It's still the concrete implementation inside the DLL class TaskImpl and not the derivates defined by class AppImpl.
And basically this is my problem: I want to use a default implementation from inside a DLL, but I want to be able to expand it on the Application side, so unless I have explicitly overriden a function in ApplImp.h, I fall back to the one defined in TaskImpl inside the DLL.
Is this possible? If so, what am I doing wrong? If not, how could I accomplish something equivalent?
I already toyed with exporting both "TaskInterface.h" and "Task.h" and then have ApplImp.h include the concrete class in the DLL, but the compile doesn't like that for obvious reasons => can't export newTask() twice.
Any help is appreciated!
As you need to allocate and deallocate via the DLL anyway, I'd suggest providing a wrapper class alongside the DLL. This wrapper class then could be designed to be inherited from.
class Task {
public:
virtual int func1(void) = 0;
virtual int func2(void) = 0;
};
// v~~~~v probably dllimport in the header you ship
extern "C" __declspec(dllexport) Task * APIENTRY newTask();
class TaskWrapper {
public:
TaskWrapper() : m_ptr( newTask() ) {}
virtual ~TaskWrapper() { deleteTask(m_ptr); }
virtual int func1(void) { m_ptr->func1(); }
virtual int func2(void) { m_ptr->func2(); }
protected: // implementation omitted for brevity
TaskWrapper(TaskWrapper const&);
TaskWrapper(TaskWrapper&&);
TaskWrapper& operator= (TaskWrapper const&);
TaskWrapper& operator= (TaskWrapper&&);
private:
Task* m_ptr; // preferably a unique_ptr
};
You could also let TaskWrapper derive from Task.
If I understand the question correctly, you want ApplImp to derive from TaskImp, and call into TaskImpl member implementations as needed, using standard C++ syntax..
You can't do that directly because the application and DLL are linked separately and have no compile-time knowledge of each other. The application doesn't know about TaskImpl at compile time, thus the compiler cannot derive from it and cannot create a Vtable that may be a combination of funcitons from application and DLL.
You chould compose the objects, i.e. create an instance of TaskImp inside ApplImp and delegate all functions to the TaskImp instance inside of ApplImp. That's inconvenient in many cases.
A more convenient way is to export the implementation of TaskImpl from the DLL: declare the whole class as __dllexport. Unfortunately, that's the least portable way to do it and in a large project, it may lead to a huge dll export section with 10000 C++-name-mangled entries. But you might be able to use TaskImpl as a base class in other DLLs or the application.
Btw, this won't compile because ApplImp is derived from Task, and Task* cannot be cast implicitly to ApplImpl.
ApplImp * aNewTask = static_cast(newTask());
I'm following this singleton pattern, why error LNK2001: unresolved external symbol in this case? my problem LOOKs similar, but my issue is not with the definition of the static instance. My problem is is resolving the static GetInstance() definition from another class.
My errors seems different, or previous answers are inadequate. I've tried the suggestions, "You need to define s_instance outside the class" which doesn't make sense to me as a cpp noob. I declare the statics in the header, and define their implementation in the cpp as well.
I also don't need a lecture on thread safety of singletons, handler bindings use signals2...
State.h
class State
{
public:
State(void);
~State(void);
static State* instance;
static State* GetInstance();
...
};
State.cpp
State::AppState mCurrentState;
boost::signals2::signal<void ()> mSignal;
State* instance = NULL;
State* GetInstance()
{
if( instance == NULL)
{
instance = new State();
return instance;
}
else
{
return instance;
}
}
All that compiles fine. Then when I try to access the singleton like this
State *state = State::GetInstance();, I get 'unresolved external symbol' error.
error LNK2019: unresolved external symbol "public: static class State * __cdecl State::GetInstance(void)" (?GetInstance#State##SAPAV1#XZ) referenced in function "public: virtual void __thiscall MesherApp::setup(void)" (?setup#MesherApp##UAEXXZ)
Also tried the following since some say "define outside of class" - what does that even mean?
class State
{
public:
...
}
static State* instance;
static State* GetInstance();
Looking at this question, Static method with a field I don't see how this applies. I am declaring in the .h and defining everything in the cpp file.
Can you simplify?
class State
{
public:
static State& GetInstance()
{
static State _instance;
return _instance;
}
};
See, it's hidden, it's on-demand, it's thread safe and it works without hoop-jumping.
The static initialization ensure the equivalent of instance == NULL there without any additional effort. It also ensures proper destruction at (before) process shutdown (assuming normal termination).
The only assumption this made is that you don't want to be able to 'forcibly' reset the singleton instance.
I think sehe answer is appropriate and if I would ever find my self using singleton I would take that root.
On the other hand the problem with your code is here:
State* instance = NULL;
It should be
State* State::instance = NULL;
I also just noticed another mistake which is:
State* GetInstance()
{
//...
}
should be:
State* State::GetInstance()
{
//...
}
gsoap with its tools wsdl2h and soapcpp2 provided me with a soapStub.h file containing the following:
class SOAP_CMAC ns2__SOAPKunden
{
public:
std::string *adresszusatz;
// ...
public:
virtual int soap_type() const { return 7; }
// ...
ns2__SOAPKunden() : adresszusatz(NULL), x(NULL) { } // left out all member init.
virtual ~ns2__SOAPKunden() { }
};
I start with a small app using the class to populate objects with data from informix DB.
But to compile successfully i have to leave away all the virtual stuff - i found many postings about this error and use of virtual members in subclasses - otherwise i get
main.o: In function `ns2__SOAPKunden::ns2__SOAPKunden()':
main.cpp:(.text._ZN15ns2__SOAPKundenC1Ev[ns2__SOAPKunden::ns2__SOAPKunden()]+0xf): undefined reference to `vtable for ns2__SOAPKunden'
main.o: In function `ns2__SOAPKunden::~ns2__SOAPKunden()':
main.cpp:(.text._ZN15ns2__SOAPKundenD1Ev[ns2__SOAPKunden::~ns2__SOAPKunden()]+0x13): undefined reference to `vtable for ns2__SOAPKunden'
collect2: ld returned 1 exit status
I admit after years of scripting only it's very hard for me to make sense of C++ code... I want to ask for any advice what to try next. My class is no derived class, is for example what makes me wonder.
The error means that the virtual table has not been correctly compiled/linked in the final binary (executable or library). There are two common circumstances that lead to this error:
you are not linking the object file that includes the virtual table definitions --i.e. you compiled soapStub.cpp into soapStub.o, but did not add that binary to the linker command line.
the compiler is not generating the virtual table anywhere, so even if you are including all object files, that does not include the virtual table.
The second case is the hardest to identify for non-experienced developers, and can be caused by a class that is defined in the header and contains virtual functions. If all the virtual functions are defined inlined, the compiler will generate the virtual table in all translation units that include the header, and mark it as a weak symbol so that the linker can discard them, but if you later add a new virtual method and you leave it undefined in the header --or if you remove the definition from one of the virtual functions--, then the compiler will not generate the virtual table in each translation unit, but only in the one that defines those functions.
Things to check:
you are linking all object files
either all virtual functions are defined inline in the class definition or you have a .cpp that defines the virtual functions and you are linking that in.
This is what David Rodriguez said, just stated simpler I guess...
I had this situation in my interface class:
class IBase
{
public:
virtual void begin(unsigned long);
virtual void end();
virtual int available(void) = 0;
virtual int peek(void) = 0;
virtual int read(void) = 0;
virtual void flush(void) = 0;
}
and changed it to this:
class IBase
{
public:
virtual void begin(unsigned long) = 0;
virtual void end() = 0;
virtual int available(void) = 0;
virtual int peek(void) = 0;
virtual int read(void) = 0;
virtual void flush(void) = 0;
}
which did the trick.
begin() and end() were defined in derived class in a different file, IBase class (interface) was only declared in header and included in few places.
Error from OP only appeared when I set optimizations to none (-O0), any other setting resulted in no error (gcc 4.8).