By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,601 Members | 989 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,601 IT Pros & Developers. It's quick & easy.

How to use Singletons over dll boundaries?

P: 1
Hi all,

actually i migrate our Linux sources to windows using MSYS/MinGW. Now I've to migrate several global utility singletons (template based) , which are placed in a shared library, everything is working fine with Linux and in context of the dll.

The singleton:
Expand|Select|Wrap|Line Numbers
  1. template <class T>
  2.  
  3. class brSingleton
  4. {
  5. public:
  6.     static T& getInstance(){
  7.         if(m_instance == 0)
  8.             m_instance = new T;
  9.  
  10.         return *m_instance;
  11.     }
  12.  
  13.     virtual void delInstance(){
  14.         delete(m_instance);
  15.         m_instance = 0;
  16.     }
  17.  
  18. protected:
  19.     brSingleton() {}
  20.     virtual ~brSingleton()  {}
  21.  
  22. private:
  23.     brSingleton(const brSingleton& s) {}
  24.     const brSingleton& operator=(const brSingleton& s) const {}
  25.     brSingleton& operator=(const brSingleton& s) {}
  26.  
  27.     static T*    m_instance;
  28. };
  29.  
  30. template <class T>
  31. T* brSingleton<T>::m_instance = 0;
  32.  
But I'm getting errors when I try to use it from several different dll's, while got different singleton instances in those dll's. I tried to use the windows dllimport/export macros but i fail.

The import/export macros in brCommons.h
Expand|Select|Wrap|Line Numbers
  1. #ifdef WIN32
  2.   #ifdef MYLIB_EXPORTS
  3.     #define MYLIB_API __declspec(dllexport)
  4.   #else
  5.     #define MYLIB_API __declspec(dllimport)
  6.   #endif
  7. #else
  8.   //define empty values for linux OS
  9.   #define MYLIB_API
  10. #endif
  11.  
The concrete singleton header:
Expand|Select|Wrap|Line Numbers
  1. class MYLIB_API brConfiguration : public brCore::brSingleton<brConfiguration>
  2. {
  3.     friend class brCore::brSingleton<brConfiguration>;
  4.  
  5. public:
  6.     enum Types {
  7.         INT,    // 0
  8.         LONG,   // 1
  9.         UINT,   // 2
  10.         ULONG,  // 3
  11.         FLOAT,  // 4
  12.         DOUBLE, // 5
  13.         STRING, // 6
  14.         CHAR,   // 7
  15.         ANY     // 8
  16.     };
  17.  
  18.     struct valuetype{
  19.         brAnyType value;
  20.         Types type;
  21.     };
  22.  
  23.    void setValue(std::string key, const int& value);
  24.    void setValue(std::string key, const long& value);
  25.    void setValue(std::string key, const unsigned int& value);
  26.    void setValue(std::string key, const unsigned long& value);
  27.    void setValue(std::string key, const float& value);
  28.    void setValue(std::string key, const double& value);
  29.    void setValue(std::string key, const std::string& value);
  30.    void setValue(std::string key, const char* value);
  31.    void setAnyValue(std::string key, brAnyType value);
  32.  
  33.    // handling lex_t uses.
  34.    brAnyType getValue(std::string key, brAnyType default_value = 0);
  35.  
  36.    valuetype getInternalValue(std::string key);
  37.  
  38. protected:
  39.    brConfiguration();
  40.    virtual ~brConfiguration();
  41.    void setValue(std::string key, brAnyType value, Types type);
  42.  
  43. private:
  44.    typedef std::map<std::string,valuetype> MapT;
  45.    MapT m_configs;
  46. };
  47.  
And the concrete singleton cpp module header to force an dll export and template export:

Expand|Select|Wrap|Line Numbers
  1. // Ensure that the dll hader will be exported
  2. #define MYLIB_EXPORTS
  3. #include <brConfig/brConfiguration.h>
  4.  
  5. // You must also export the template instantiation Singleton< MyClass > into 
  6. // the DLL you are compiling. That should be it!
  7. template MYLIB_API class binrev::brCore::brSingleton<brConfiguration>; 
  8.  
Knows anyone a solution?
I'm thankfully for any hint or point in the right direction.

Best regards,
Chris

P.S.: You could get the complete test source here: http://sourceforge.net/projects/binr...st.7z/download

I've included two executables in the lib subfolder demonstrating the problem. The ConfigTest.exe shows that the singleton works fine in dll context, the SingletonTest.exe demonstrating the problem using te singleton across differend dll's.
Sep 10 '10 #1
Share this Question
Share on Google+
1 Reply


weaknessforcats
Expert Mod 5K+
P: 9,197
It does not appear that the singleton is set up correctly.

Using multiple dlls should njot be a problem. Using multiple threads will be an issue since the code is not thread safe.

The singleton needs a global point of acess and there needs to be exactly one singleton instance for the entire progem regardless of the number of dlls.

I also believe there is a design weakness due to the use of friend classes. A friend class breaks encapsulation and that's a no-no.

Read this: http://bytes.com/topic/c/insights/65...erns-singleton
Sep 10 '10 #2

Post your reply

Sign in to post your reply or Sign up for a free account.