duplicate singleton on Windows-platform

Chris Bielow bielow@mi.fu-berlin.de
Thu Feb 7 15:19:00 GMT 2008


Thanks for your quick response everybody!

I came a little closer to solving the problem...

The problem was, that I there existed *two* object files (one in the 
shared lib, one in the executable) of the Factory at runtime.

To solve this I only declared the instance() function of Factory.h when 
including it in an executable, but defined it within the Library. This
causes the linker to use the object from the lib.

----------- Factory.h ----------
...
/// singleton access to Factory
static Factory* instance()
#ifdef OPENMS_WITHIN_LIB
{
   if (!instance_ptr_)
   {
     instance_ptr_ = new Factory();
     FactoryProduct::registerChildren();
   }
   return instance_ptr_;
}
#else
;
#endif
----------- END Factory.h -----------

Now it works on Windows as well.

BUT: new problem.
If the executable wants to instanciate a new kind of Factory (other 
Template parameter), the compilation fails, because the instance() 
method is only declared, but not defined.

How can I convince the linker to use instances of the Factory from the 
Lib and creating new instances only if they are not present in the Lib.

One option would be to instanciate every Factory within the lib that 
might be used by an executable.. but thats rather nasty.

cheers
Chris



Kai Tietz schrieb:
> binutils-owner@sourceware.org wrote on 06.02.2008 20:07:15:
> 
> 
>>Hi,
>>
>>I'm having trouble creating a "real" singleton on Windows (MinGW 
>>Binutils 2.18) when linking my the executable against the shared version 
> 
> 
>>my library (all C++). Under Linux everything is fine.
>>The Singleton is a static member of template class.
>>
>>------------- Factory.h ----------------
>>template <typename FactoryProduct>
>>class Factory
>>{
>>   static Factory* instance()
>>   {
>>     if (!instance_ptr_)
>>     {
>>       std::cout << "INITIALIZING ... "
>>       instance_ptr_ = new Factory();
>>       FactoryProduct::registerChildren();
>>     }
>>     return instance_ptr_;
>>   }
>>
>>   ...
>>
>>private:
>>
>>  static Factory* instance_ptr_;
>>}
>>template<typename FactoryProduct> Factory<FactoryProduct>* 
>>Factory<FactoryProduct>::instance_ptr_ = 0;
>>
>>----------- END Factory.h ---------
>>
>>The Factory.h header is included in some of the classes (**) that are 
>>compiled into the shared library.
>>
>>Now, if I write a test program that uses this library, there seem to be 
>>multiple instances, as I get :
>>
>>INITIALIZING ...
>>INITIALIZING ...
>>
>>, which does NOT happen when linking the executable with the static 
>>version of the library.
>>btw: The test program also includes the Factory.h header, because it 
>>contains something like:
>>----------- Test.Cpp -----------
>>DataReducer* p = Factory<DataReducer>::create("max_reducer");
>>----------- END Test.Cpp -----------
>>
>>If use the following commands to create the library under Windows:
>>
>>dynamic:
>>/mingw/bin/g++ -Wl,--export-dynamic -shared -o libOpenMS.dll \
>>     -Wl,--export-all-symbols \
>>     -Wl,--enable-auto-import \
>>     -Wl,--whole-archive <list of objects to add> \
>>     -Wl,--no-whole-archive <other dependent libs> \
>>     -Wl,--large-address-aware
>>
>>static:
>>/mingw/bin/ar cru libOpenMS.a <list of objects to add>
>>
>>under linux something like:
>>/usr/bin/g++ -shared -fPIC -o libOpenMS.so <list of objects to add> -lm
>>
>>does suffice (and it works).
>>
>>So, to summarize:
>>
>>Linux
>>  -static (.a): OK
>>  -dynamic(.so): OK
>>Windows (MinGW)
>>  -static (.a): OK
>>  -dynamic(.dll): FAILED - why?
>>
>>
>>
>>Any ideas why that happens?
> 
> 
> Your code is not valid, if you include the header at more than one place, 
> because in each instance the static is redeclared. But you could use the  
> __declspec(selectany) attribute on the variable for mingw to solve this 
> problem.
> 
> Cheers,
>  i.A. Kai Tietz
> 
> |  (\_/)  This is Bunny. Copy and paste Bunny
> | (='.'=) into your signature to help him gain
> | (")_(") world domination.
> 
> ------------------------------------------------------------------------------------------
>   OneVision Software Entwicklungs GmbH & Co. KG
>   Dr.-Leo-Ritter-Straße 9 - 93049 Regensburg
>   Tel: +49.(0)941.78004.0 - Fax: +49.(0)941.78004.489 - www.OneVision.com
>   Commerzbank Regensburg - BLZ 750 400 62 - Konto 6011050
>   Handelsregister: HRA 6744, Amtsgericht Regensburg
>   Komplementärin: OneVision Software Entwicklungs Verwaltungs GmbH
>   Dr.-Leo-Ritter-Straße 9 – 93049 Regensburg
>   Handelsregister: HRB 8932, Amtsgericht Regensburg - Geschäftsführer: 
> Ulrike Döhler, Manuela Kluger
> 
> 

-- 
Freie Universitaet Berlin
Institut fuer Informatik              Phone: +49 30 838 75244
AG Algorithmische Bioinformatik       room 011
Takustr. 9
D-14195 Berlin



More information about the Binutils mailing list