How does Ogre share singleton object in different DLLs? - c++

In OgreMain project
OgrePrerequisites.h
#define _OgreExport __declspec( dllexport )
OgreSingleton.h
template<typename T>
class Singleton
{
private:
Singleton(const Singleton<T> &);
Singleton& operator=(const Singleton<T> &);
protected:
static T* msSingleton;
public:
Singleton(void)
{
assert(!msSingleton);
msSingleton = static_cast<T*>(this);
}
~Singleton(void)
{
assert(msSingleton); msSingleton = 0;
}
static T& getSingleton(void)
{
assert(msSingleton); return (*msSingleton);
}
static T* getSingletonPtr(void)
{
return msSingleton;
}
};
OgreRoot.h
class _OgreExport Root : public Singleton<Root>
{
};
Files above are compiled into OgreMain.lib
In RenderSystem_GL project
OgreGLPlugin.cpp
void GLPlugin::install()
{
mRenderSystem = new GLRenderSystem();
Root::getSingleton().addRenderSystem(mRenderSystem);
}
OgreGLPlugin.cpp is compiled into RenderSystem_GL.dll
Ogre share a unique Root object in OgreMain and RenderSystem_GL. How did Ogre make it?
Here is my code.
class DllDemoA in DllDemoA.dll
class __declspec(dllexport) DllDemoA: public Singleton<DllDemoA>
{
public:
DllDemoA()
{
// always assert error
DllDemoB::getSingleton();
}
};
__declspec(dllexport) void Create()
{
DllDemoA* a = new DllDemoA();
}
class DllDemoB in DllDemoB.lib
class __declspec(dllexport) DllDemoB: public Singleton<DllDemoB>
{
};
main.exe link DllDemoB.lib, dynamically load DllDemoA.dll
int main()
{
DllDemoB* b = new DllDemoB();
// no assert error
DllDemoB::getSingleton();
HINSTANCE hMod = LoadLibrary("DllDemoA.dll");
typedef void(*Func)();
Func func = (Func)GetProcAddress(hMod, "Create");
if (func)
{
func();
}
return 0;
}

Related

Call C++ virtual functions through C struct of function pointers

I'm creating a C-wrapper for a C++ class:
class IObject {
public:
virtual int getValue() const;
virtual ~IObject() = default;
};
class Object: public IObject {
public:
virtual int getValue() const { return 123; }
};
Inspired openh264's C API, I have the following code:
// object.h
#pragma one
#ifdef __cplusplus
class IObject {
public:
virtual int getValue() const = 0;
virtual ~IObject() = default;
};
extern "C" {
#else
typedef struct IObjectVtable IObjectVtable;
typedef IObjectVtable const* IObject;
struct IObjectVtable {
int (*getValue)(IObject*);
};
#endif
int makeObject(IObject**);
int freeObject(IObject*);
#ifdef __cplusplus
} // extern "C"
#endif
// object.cpp
#include "object.h"
class Object : public IObject {
public:
virtual int getValue() const override { return 123; }
};
extern "C" {
int makeObject(IObject** obj) {
*obj = new Object;
if (*obj == nullptr) {
return 1;
}
return 0;
}
int freeObject(IObject* obj) {
delete obj;
return 0;
}
}
In main.c, I use Object as follows:
#include <stdio.h>
#include "object.h"
int main() {
IObject* obj;
makeObject(&obj);
printf("%d\n", (*obj)->getValue(obj)); /** Calling getValue */
freeObject(obj);
return 0;
}
The code compiles and correctly prints "123", but I need to pass obj as an argument of getValue(). Is it possible to avoid this, i.e., simply call obj->getValue()?
According to the documentation, openh264 can do that, but I don't understand how/why it works:
ISVCDecoder *pSvcDecoder; //similar to IObject* obj;
WelsCreateDecoder(&pSvcDecoder); //similar to makeObject(&obj);
pSvcDecoder->Initialize(&sDecParam); //similar to obj->getValue();
// not (*obj)->getValue(obj)

C++ Factory of templated sigleton

Here a simple project in C++ with 2 design pattern: singleton and factory, sigleton is a templated class too and an interface (IHash) and a class (Hash1).
A simple factory class (HashFactory) creates a sigleton (Hash1); Hash1 inherits the interface IHash and ideally i've Hash1, Hash2 .. HashN.
In compile time i've an error, what's the problem?
g++ main.cpp
main.cpp: In static member function ‘static IHash* HashFactory::get(int)’:
main.cpp:11:15: error: ‘static T& Singleton<T>::getInstance() [with T = Hash1]’ is inaccessible
static T &getInstance() {
^
main.cpp:76:50: error: within this context
if (type == 1)return &Hash1::getInstance();
^
Cut and paste this code to compile it:
#include <iostream>
using namespace std;
///////////////////////////////////////////////
//Class Singleton
template<class T>
class Singleton {
public:
static T &getInstance() {
if (!_instanceSingleton) {
_instanceSingleton = new T();
}
return *_instanceSingleton;
}
private:
static T *_instanceSingleton;
};
template<class T> T *Singleton<T>::_instanceSingleton = 0;
/////////////////////////////////////////////////
//Interface IHash
class IHash {
public:
void function1() {
cout << "function1";
}
virtual void recordHash(bool b) = 0;
~IHash() {
dispose();
}
private:
void dispose() {
cout << "dispose\n";
}
};
///////////////////////////////////////////////////
//Class Hash1 is a singleton and inherits IHash
class Hash1 : public IHash, Singleton<Hash1> {
friend class Singleton<Hash1>;
public:
void recordHash(bool b);
private:
//private constructor, is a sigleton
Hash1();
};
Hash1::Hash1() {
cout << "create Hash1\n";
}
void Hash1::recordHash(bool b) {
cout << b << " recordHash\n";
}
////////////////////////////////////////////////////
//Factory for IHash
class HashFactory {
public:
static IHash *get(int type) {
if (type == 1)return &Hash1::getInstance();
// if (type == 2)return &Hash2::getInstance();
// if (type == 3)return &Hash3::getInstance();
return 0;
}
};
//////////////////////////////////////////////////////
int main() {
int type=1;
IHash *a = HashFactory::get(type);
a->recordHash(true);
a->function1();
return 0;
}
Hash1's inheritance from Singleton<Hash1> is implicitly private. Change that to
class Hash1 : public IHash, public Singleton<Hash1> {

Mocking a class having private Constructor using GMOCK

I have a Singleton class with private Ctor, Dtor and one getInstance() method.
class Single {
public:
virtual void* alloc(size_t size, uint line){}
Single* getInstance() {
if(!m_Instance)
m_Instance = __OSAL_NEW OSAL_Memory;
return m_Instance;
}
private:
Single();
~Single();
static Single* m_Instance;
};
#define Allocate(size_t size)\
(Single::getInstance())->alloc(size, __LINE__)
I need to Mock this class using GMOCK.
Is there any way around to mock it.
You could use factory pattern to create your object.
#include <iostream>
#include <functional>
struct A
{
virtual ~A(){}
virtual void foo() = 0;
};
struct Areal : A
{
virtual void foo(){
std::cout<<"real"<<std::endl;
}
};
struct Amock : A
{
virtual void foo(){
std::cout<<"mock"<<std::endl;
}
};
struct Single
{
typedef std::function< A*() > CreatorFn;
static A* getInstance(){
if ( ! instance() )
instance() = (create())();
return instance();
}
static void setCreator( CreatorFn newFn ){
create() = newFn;
}
private:
static CreatorFn& create(){
static CreatorFn f( [](){return new Areal;} );
return f;
}
static A*& instance(){
static A* p=nullptr;
return p;
}
};
bool useMock = true;
int main()
{
if ( useMock )
{
Single::CreatorFn mockFn( [](){ return new Amock; } );
Single::setCreator( mockFn );
}
Single::getInstance()->foo();
}
You just have to make sure that you set the creator before accessing the instance. Otherwise, a default creator function is going to be invoked.

Singleton Abstract Factory Pattern

I would like to implement a Abstract Factory pattern but also would like to be a singleton.
class WindowFactory {
protected:
virtual Scrollbar* createScrollbar() = 0;
};
class MacWindowFactory: public WindowFactory {
virtual Scrollbar* createScrollbar() {
//return a instance
}
;
};
class LinuxWindowFactory: public WindowFactory {
virtual ScrollBar* createScrollbar() {
//return a instance
}
;
};
Can someone help me with some sample code of making this Abstract Factory Singleton ?
Thanks in advance.
I managed to come up with more elegant solution ( No error checking as of now ). Kindly let me know your thoughts
#include<iostream>
#include<map>
class AbstractFactory
{
private:
typedef std::map< std::string, AbstractFactory* > ClientMap;
static ClientMap s_clientMap;
public:
void virtual createScrollbar() = 0;
void virtual createWindow() = 0;
static AbstractFactory* createInstance( std::string client );
protected:
void Register( std::string, AbstractFactory* );
};
AbstractFactory::ClientMap AbstractFactory::s_clientMap;
class LinuxFactory: public AbstractFactory
{
public:
void createScrollbar()
{
std::cout<<"Scrollbar for Linux"<<std::endl;
}
void createWindow()
{
std::cout<<"WIndow for Linux"<<std::endl;
}
private:
LinuxFactory()
{
Register( "Linux", this );
}
LinuxFactory( const LinuxFactory& );
static LinuxFactory s_LinuxFactory;
};
LinuxFactory LinuxFactory::s_LinuxFactory;
class MacFactory: public AbstractFactory
{
public:
void createScrollbar()
{
std::cout<<"Scrollbar for Mac"<<std::endl;
}
void createWindow()
{
std::cout<<"WIndow for Mac"<<std::endl;
}
private:
MacFactory()
{
Register( "Mac", this );
}
MacFactory( const MacFactory& );
static MacFactory s_MacFactory;
};
MacFactory MacFactory::s_MacFactory;
void AbstractFactory::Register( std::string clientName, AbstractFactory* factory )
{
s_clientMap.insert( ClientMap::value_type( clientName, factory ) );
}
AbstractFactory* AbstractFactory::createInstance( std::string client )
{
return s_clientMap.find( client )->second;
}
int main()
{
AbstractFactory *factory = AbstractFactory::createInstance( "Linux" );
factory->createScrollbar();
factory->createWindow();
}
If you need an actually dynamic abstract factory, you'd need to somehow set it up at run-time. You can do this by having a function selecting the desired factory with a suitable function which just sets up the actual singleton. In a real application you would probably have some sort of registration function where you can register functions getting an instance for the factory (factory factory functions). In the example below I used a simple set up where the available factories are known at compile time.
#include <memory>
#include <stdexcept>
#include <string>
class Scrollbar;
class WindowFactory {
public:
static void setFactory(std::string const&);
static Scrollbar* createScrollbar();
virtual ~WindowFactory() {}
private:
virtual Scrollbar* doCreateScrollbar() = 0;
};
class MacWindowFactory
: public WindowFactory {
friend void WindowFactory::setFactory(std::string const&);
virtual Scrollbar* doCreateScrollbar() {
return 0;
}
};
class LinuxWindowFactory
: public WindowFactory {
friend void WindowFactory::setFactory(std::string const&);
virtual Scrollbar* doCreateScrollbar() {
return 0;
}
};
// in WindowFactory.cpp
static std::auto_ptr<WindowFactory>& getPointer()
{
static std::auto_ptr<WindowFactory> pointer;
return pointer;
}
Scrollbar* WindowFactory::createScrollbar()
{
return getPointer().get()
? getPointer()->doCreateScrollbar()
: throw std::runtime_error("WindowFactory not set");
}
void WindowFactory::setFactory(std::string const& what)
{
if (what == "Mac") {
getPointer() = std::auto_ptr<WindowFactory>(new MacWindowFactory());
}
else if (what == "Linux") {
getPointer() = std::auto_ptr<WindowFactory>(new LinuxWindowFactory());
}
else {
throw std::runtime_error("unknown factory: '" + what + "'");
}
}
namespace WindowFactory {
Scrollbar* createScrollbar() {
#ifdef TARGET_OS_MAC
...
#elif __linux__
...
#endif
}
};
It's how I would've done it.

abstract class and static methods

I have an abstract class:
class A
{
public:
bool loaded_;
virtual int load() = 0;
}
And several derived classes :
class B:public A
{
public:
int load();
static B& instance();
}
class C:public A
{
public:
int load();
static C& instance();
}
The fact is that the code inside ::instance() methods is the same for each class :
static B& B::instance()
{
static B instance_;
if (!instance_.loaded_)
{
instance_.load();
instance_.loaded_=true;
}
return instance_;
}
static C& C::instance()
{
static C instance_;
if (!instance_.loaded_)
{
instance_.load();
instance_.loaded_=true;
}
return instance_;
}
I would like to factorize this ::instance method, but given that it uses the virtual method ::load, i cannot define it in the class A.
Theoretically, i know it's weird since the class A should have 0 instance and B,C should have 1 instance but it also makes sense that this code should be factorized.
How would you solve that problem ?
You could make instance() a free function template:
template<class T>
T& instance()
{
static T instance_;
if (!instance_.loaded_)
{
instance_.load();
instance_.loaded_=true;
}
return instance_;
}
Then you can use it like this:
instance<B>().do_stuff()
This is a common usage of the CRTP, define the function that creates the instance in the template and then instantiate it in each type:
struct A {
virtual ~A() {} // don't forget to make your destructor virtual!
virtual void load() = 0;
};
template <typename T>
struct instance_provider {
static T& instance() { /* implementation */ }
};
struct B : A, instance_provider<B> {
virtual void load();
};
struct C : A, instance_provider<C> {
virtual void load();
};