views:

232

answers:

7

I have a class which needs to be a singleton. It implemented using a static member pointer:

class MySinglton
{
public:
    static MySinglton& instance() { ... }
private:
    static MySinglton* m_inst;
};

This class is compiled into a .lib which is used in multiple dlls in the same application. The problem is that each dll sees a different m_inst. since it is compiled and linked separatly.

What is simple way to solve this problem?

Separating the .lib to its own dll is not an option. it must be a .lib.

A: 

I don't know if you consider this simple, but you'll need to allocate a "master instance" (on the heap, say) and then let all your MySingleton instances refer to the "master instance".

S.C. Madsen
Yes, but how are all of the instances going to know about this master instance?
shoosh
As Denes Tarjan pointed out, the "master instance" could be communicated to all instances by the application during initialization
S.C. Madsen
A: 

C++ has no built-in mechanism for sharing variables in the way you seem to want. The only solution is to pass the single instance as a function parameter, using a pointer or reference.

anon
A: 
Tryum
"Separating the .lib to its own dll is not an option. it must be a .lib."
shoosh
Each instance of the DLL will get its own copy of the variable, which is not what it seems he wahts.
anon
Actually, you can share data throught a DLL : http://msdn.microsoft.com/en-us/library/h90dkhs0(VS.80).aspx
Tryum
That technique has LOTS of issues. Particularly, managing the lifetime of the shared object becomes almost impossible.
anon
+1  A: 

One way solving the problem is that creating a shared memory, and creating the object in the shared memory. The two modules still have two copies of the pointers, but they point to the same location i.e. same instance of an object.

leiz
-1, read the question again. The dlls are mapped into the same address space.
avakar
@avakar, how does that matter? Using named shared memory is just a way of commutation even in the same program.
leiz
My bad, I see your point now and have removed the down-vote. I had to make a minor edit so that SO would allow the vote change.
avakar
A: 

I would use the shared memory mechanism provided by your os, MapViewOfFile or shmem. This might go:

class MySinglton
{
    public:
        static MySinglton& instance() {
            static MySinglton* m_inst = get_shared();
            return *m_inst;
        }
    private:
        static MySinglton * get_shared()
        {
            //1. Try to open shared memory, handle = OpenFileMapping.
            //2. If successful, return MapViewOfFile(handle).
            //3. Else, allocate enough space using CreateFileMapping, sizeof(MySingleton).
            //4. Initialise MapViewOfFile(handle), return MapViewOfFile(handle).
        }

        void Initialise()
        {
            // Stuff you would normally do in operator new here.
        }

};
avid
A: 

A solution could be transferring the instantiation to the application, and the DLLs will get reference to it during initialization. It may not be as elegant as you'd like, but it would do it.

Need to know what's the REAL problem behind your question. The answer may not be in the form you expect it. ;)

Denes Tarjan
... It doesn't get any more REAL than this. two dlls, one lib, two instances.
shoosh
hmm... "If the mountain does not go to Mohammad, let Mohammad go the mountain." ;) I'm sorry.
Denes Tarjan
A: 

There is no simple solution to your problem. Questions: If there is no solution shoosh what are you going to do? Abandon the project? Or re-structure it so the 'must be a .lib' constraint is removed? If this problem concerns a commercial project what are you going to say to the project manager, stakeholders, etc?

Sam
I'm going to tell them I'm using shared memory to make sure all of the instances have the same pointer... which is not as simple a solution as I hoped. What's up with the attitude?
shoosh
Just professional curiosity about the context of the problem, how it came to be and asking what-if questions. I am sure that other C++ developers are asking these and other questions in their minds. I apologise if you have taken offence; none was intended.
Sam