Thread: windows .dll vs. linux .so - global static objects

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    519

    windows .dll vs. linux .so - global static objects

    Hi,

    a singleton (static, global) object is used from the main app as well as from an dynamical loaded .so/.dll

    I observe the following differences in behavior under linux and windows:

    under linux the object is created once, at the first call to the singletons instance function (i checked with debug output in the ctor of the class)

    but under windows the object is created twice: one time when the main app calls instance() the first time and a second time when instance() is called from the dll for the first time. As you can imagine that behavior really sucks if you want to access consistent data stored in the singleton object from the main app as well as from the dll.

    Is there any way to get the behavior under windows/dll exact like under linux/so?

    Thank you.

  2. #2
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    i found that topic discussed here:
    http://209.85.129.104/search?q=cache:viXJGiItkIcJ:www.devmaster.net/forums/showthread.php%3Ft%3D1729+singleton+dll&hl=en&ct=c lnk&cd=15&gl=de

    in the third post that guy anubis says:
    especially since i see no real need for this class at all. the thing is that as soon as you start using dlls your singleton pointer won't work over library boundaries because each dll would reimplement the static pointer locally. to solve this you would have to provide a static overload of the getSingleton method in each class that derives from Singleton. what remains is that you have abstracted the storage of the singleton pointer in a hacky and ugly way (the static_cast would take away the uglyness but still the whole thing would be more of an OOP beautification than being really useful)
    but I'm to silly to understand what exactly he means. could anyone translate his solution
    to solve this you would have to provide a static overload of the getSingleton method in each class that derives from Singleton.
    down to my level of understanding?

  3. #3
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    even the german (but not the english) wikipedia does write about that problem

    In DLLs (dynamic link libraries) lassen sich (zumindest in C++) Singletons nur eingeschränkt verwenden. Da DLLs nicht wie zum Beispiel Libraries zum Programm gelinkt werden, sondern von Haus aus gelinkt sind, wird ein Singleton, das in einer DLL und dem Hauptprogramm verwendet wird, in beiden Modulen ein eigenes Objekt sein. Das kann man (umständlich) vermeiden, indem das Hauptprogramm die eigene Instanz des Singleton an die DLL übergibt (dies ist ein Spezialfall des oben erwähnten "Scope"-Problems).
    I'm trying to translate

    In DLL's in (C++) singletons are just of limited use. Because unlike libraries (I think he's talking about static ones), DLL's are not linked to the program. they rather are life-time linked (don't ask me about this, I don't understand it even in german). A singleton used by the main application and a DLL is going to be a seperate object in both modules.
    This can intricately be avoided by letting the main application pass the own instance of the singleton to the DLL. This is a special case of the mentioned scope problem (of singletons)
    So it looks like my only chance is to pass a pointer to the singleton object to the dll. I still have no idea how to do that

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by pheres View Post
    So it looks like my only chance is to pass a pointer to the singleton object to the dll. I still have no idea how to do that
    Create the singleton in the main application, and pass a pointer to the DLL init-function - which part of this do you find difficult?

    --
    Mats

  5. #5
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    init() is the function executed while the call to LoadLibrary(). How should I pass things to it?
    And where should I store that pointer so that classes defined in the dll are able to access it?

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by pheres View Post
    init() is the function executed while the call to LoadLibrary(). How should I pass things to it?
    And where should I store that pointer so that classes defined in the dll are able to access it?
    No, you add a separate "manual" init that you call from (say) your main() function.

    --
    Mats

  7. #7
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Hm, dividing the singleton code up into .h/.cpp seems to solve the problem. DLL and main app seems to access the same object now. Strange, I don't understand that...like many things windows does...

  8. #8
    Registered User
    Join Date
    Nov 2010
    Posts
    2

    windows .dll vs. linux .so - global static objects

    Hi,

    Even i am facing the same problem with static objects which is created twice in windows..

    I tried all solutions which you have suggested but din't work out..

    It doesn't work even when i use without DLL's..

    Can anyone please help me out on this??
    Expecting for an early reply from you..

    Thanks in advance!!

  9. #9
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Just don't use static storage for data you want to access over DLL/EXE boundaries, better use 'extern' storage.
    This implies that you have to modify the implementation of the singleton pattern if you want to use it: E.g.
    singleton.h:
    Code:
    extern object* singleton_object;
    object* instance();
    singleton.cpp
    Code:
    object* singleton_object = new object;
    object* instance(){return singleton_object;}
    Then include singleton.h in every unit where you want to use it, no matter if part of the main app or some dynamic linked library.
    (Beware to not use the singleton from other global static objects).

  10. #10
    Registered User
    Join Date
    Nov 2010
    Posts
    2

    windows .dll vs. linux .so - global static objects

    Code:
    Hi,
    
    Thanks for the reply!
    I have followed the approach as per your suggestion and have come up with few doubts. Please correct me if i am wrong in any step.
    
    Find my sample code below:
    sample.hpp:
    
    class sample;
    //extern sample* singleton_object;
    sample* instance();
    class sample{
    public:	 
              int i;
    private:
              //sample();
    };
    
    sample.cpp:
    
    #include "sample.hpp"
    sample* singleton_object = new sample;
    sample* instance(){return singleton_object;}
    
    Here are the doubts:
    i> Can i pl know what is the intended use of extern in your suggestion?
        Because even without using extern my code works fine.
    
    ii> Also the constructor is not private in this approach. so, how the class can be made singleton?
    
    Please help me out!
    Awaiting for your reply..

  11. #11
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Quote Originally Posted by lakshmi.ag View Post

    Here are the doubts:
    i> Can i pl know what is the intended use of extern in your suggestion?
    Because even without using extern my code works fine.
    It instructs the linker to resolve the symbol if it finds it in a compilation unit. If you use static linkage the compiler/linker will rather duplicate the storage (so you end up with the problem you observed).
    The reason your code works w/o the extern keyword may be either because of that extern linkage is the default (I'm not sure about it) or because of that you haven't really compared the memory addresses of your "singleton" object from .exe and .dll context.

    Quote Originally Posted by lakshmi.ag View Post
    ii> Also the constructor is not private in this approach. so, how the class can be made singleton?
    By not actively calling the ctor. If you find that not satisfactorily you could try to do some trick like making it private and call it explicitly maybe from main() which could be declared as friend.
    Yes, thats not really the original singleton pattern, but to my knowledge there is no way in C++ to implement it w/o the described problems (There are others as well). I recommend to just not use it and rather control the object lifetime and construction/destruction like for any other entities.

    btw. the boost singleton library documentation has also some hints about the problems of this pattern in the c++ language:
    Chapter..1...Boost.Utility/Singleton 1.0

  12. #12
    Registered User linuxlover's Avatar
    Join Date
    Nov 2010
    Location
    INDIA
    Posts
    52
    See the problem which I posted in C board recently.................

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with Free.
    By chakra in forum C Programming
    Replies: 9
    Last Post: 12-15-2008, 11:20 AM
  2. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  3. seg fault at vectornew
    By tytelizgal in forum C Programming
    Replies: 2
    Last Post: 10-25-2008, 01:22 PM
  4. Why Linux, for the average user?
    By Hunter2 in forum A Brief History of Cprogramming.com
    Replies: 32
    Last Post: 07-07-2006, 02:36 PM
  5. Question..
    By pode in forum Windows Programming
    Replies: 12
    Last Post: 12-19-2004, 07:05 PM