Not logged in, Join Here! or Log In Below:  
 
News Articles Search    
 

 Home / General Programming / Singletons and implicitly linked DLLs Account Manager
 
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.
 
pst

March 15, 2005, 07:38 AM

I've got a singleton which needs to be shared between different dlls. However I've read that this shouldn't be possible since there are different sets of statics in different dlls.

I've got it to work in VC++.NET though if i just don't declare the "getSingletonInstance()" inline but instead put it in the source file.

All the dlls are linked implicitly.

It's something like:

  1.  
  2.  
  3. // DLL1
  4. class Singleton { ... };
  5.  
  6. // DLL2
  7. Singleton* mySingleton = Singleton::createSingleton();
  8.  
  9. // EXE
  10. Singleton* mySingletonAgain = Singleton::getSingletonInstance();
  11.  
  12.  


Is this genrally a bad thing to do and could it cause troubles later?

 
pst

March 18, 2005, 08:12 AM

:(

 
juhnu

March 20, 2005, 01:51 AM

It is possible. your singleton must reside in a dll for that to work. I recommend you to put your singleton code together with the singleton class implementation in the same dll.

in the dll header:

  1.  
  2.   class ISomething {
  3.      public:
  4.        virtual void DoSomething()=0;
  5.   };
  6.  
  7.   ISomething& GetSomethingSingleton();
  8.  

in the dll cpp
  1.  
  2.    class Something: public ISomething {
  3.        virtual void DoSomething() { ... }
  4.    };
  5.  
  6.    ISomething& GetSomethingSingleton() {
  7.       static Something something;
  8.       return something;
  9.    }
  10.  


then you can use this in any dll or compilation unit by:
  1.  
  2.   GetSomethingSingleton().DoSomething();
  3.  


 
pst

March 21, 2005, 05:47 AM

Thanks for your reply juhnu.

It works but I would however like to use a pointer instead so I can choose when to create the singleton.

I did like this, which also works for me in VC++.NET.

dll1 header

  1.  
  2. class Something {
  3. public:
  4. static Something* create();
  5. static Something* get();
  6. void doStuff();
  7. int x;
  8. };
  9.  


dll1 source
  1.  
  2. static Something* something = 0;
  3.  
  4. Something*
  5. Something::create() {
  6. something = new Something;
  7. return something;
  8. }
  9.  
  10. Something*
  11. Something::get() { return something; }
  12.  
  13. void
  14. Something::doStuff() { x += 1 }
  15.  


dll2 header not important

dll2 source (links dll1 implicitly)
  1.  
  2. DoStuff() {
  3. Something* s = Something::create();
  4. s->doStuff()
  5. }
  6.  


exe source (links dll1 and dll2 implicitly)
  1.  
  2. DoMoreStuff() {
  3. DoStuff();
  4. Something* s = Something::get();
  5. s->doStuff() // It works! s is not 0.
  6. }
  7.  


Does this work for other compilers as well?
Could any problems be caused by this implementation?

 
juhnu

March 21, 2005, 07:27 AM

the problem with your implementation is that you have to free your singleton too and can't quarantee it's really initialized before it's used for the first time. It will work though, if you can quarantee the correct execution order within all your modules.

the static local function variable handles this all quite elegantly. It does some compiler magic to ensure the instance is destroyed before the program exits and it's quite hard to beat coding it manually.

I don't understand your point with the pointers :) If it's possible for the functions to return null-pointer, then you should check it everytime before using it to avoid errors and if it's not possible for the function to return a null pointer then you could use references instead.

u do:

  1.  
  2. Something* s = Something::get();
  3. if (s) s->doStuff();
  4.  


but I'd rather do
  1.  
  2. Something::Get().doStuff();
  3.  



Andrei Alexandrescu has quite good discussion about the different singleton types in his infamous Modern C++ Design book and his Loki-library has some implementations for the need too http://sourceforge.net/projects/loki-lib/





juhani

 
pst

March 21, 2005, 05:43 PM

There's not really a problem with creation and deletion and I just left out all safety checks in the code above (as well as the destroy()-method).

If something would go wrong, for example calling the get() before create() it would be found very easily when debugging (with some error report) and it's not very likly to happen.

There won't be many singletons so it will not be very hard to keep track of them and see to that they are created and deleted correctly.

The order of creation is important since the singleton needs results from other parts of the program before it can be used correctly.

An alternative would be to have an init()-method but then it would be almost the same thing: the singleton can't be used correctly before the init()-method is called.


What I'm worried about is if get() would give me a NULL-pointer (even if the singleton is created) in some special circumstances or when using other compilers besides VC++.NET.


I checked the Loki project very briefly and it doesn't seem to deal with Singletons shared between dlls.
Here's a question related to mine:
http://sourceforge.net/forum/forum.php?thread_id=1014184&forum_id=93008
but unfortunately it didn't have an answer.

Thnaks for yor time if you've read this far :)

 
This thread contains 6 messages.
 
 
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.