This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: duplicate singleton on Windows-platform


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]