Reputation: 33784
I've got simple singleton with
class Options {
private:
Options()
{};
Options(Options const&);
void operator=(Options const&);
public:
static Options& get()
{
static Options INSTANCE;
return INSTANCE;
}
};
I've got this definition in header in shared library A
but when I call get() first from application B I see how there instance is creating and then I call methods from shared library C and using get() there I'm getting yet another instance...
How can I have something alike Application level singleton? (is it something with extern
keyword?)
Upvotes: 1
Views: 168
Reputation: 149115
It should work under windows provided:
__declspec(dllexport)
for export and __declspec(dllimport)
for importOptions::get()
is moved in a cpp file so that it only exists in the DLL.Here is an example :
options.dll build with OPTIONS_EXPORT
symbol defined:
options.h:
#pragma once
#ifdef OPTIONS_EXPORTS
#define DLLAPI __declspec(dllexport)
#else
#define DLLAPI __declspec(dllimport)
#endif
class DLLAPI Options
{
private:
Options()
{};
Options(Options const&);
void operator=(Options const&);
public:
static Options& get();
int val;
};
options.cpp:
#include "Options.h"
Options& Options::get()
{
static Options INSTANCE;
return INSTANCE;
}
A dummy c.dll using options.dll build with C_EXPORT
symbol defined and linked with options.lib
:
c.h:
#pragma once
#ifdef C_EXPORTS
#define dll __declspec(dllexport)
#else
#define dll __declspec(dllimport)
#endif
#include "../a/options.h"
namespace C {
dll Options& relay();
};
c.cpp:
#include "c.h"
Options& C::relay() {
Options& opt = Options::get();
return opt;
}
And a minimal main linked with both options.dll and c.dll:
#include <iostream>
#include "../a/options.h"
#include "../c/c.h"
int main() {
Options& o1 = Options::get();
o1.val = 12;
Options& o2 = C::relay();
std::cout << ((o1.val == o2.val) ? "Ok" : "Ko") << std::endl;
return 0;
}
Output is as expected: Ok
Upvotes: 2
Reputation: 3950
The issue is that all of your applications and libraries compile their own copy of your class into the library, since you tell all of them how the class should look.
First of, start by moving the implementation of theget
function into the source file. After this is done and you compile you should see that your shared libraries does not know how the function should look and they will not compile (linker errors except in the library that contains the class).
From there start to fix the compilation by letting the application and other libraries know where to link the function from.
On windows you need to export the class in the library that it is implemented in using __declspec(dllexport)
.
On the library and possibly the application you need to use __declspec(dllimport)
to import the class.
On Linux this should not be necessary.
Upvotes: 1