Linker dropping objects from static library problem

A

adeht

In his book, "Modern C++ Design", Andrei Alexandrescu presents a Generic
Object Factory class (Loki::Factory). One of its advantages (also mentioned
in
the book) is being able to register the class in the factory without having
a
central place that needs to be modified each time we add a new type. For
example, the registration can be done in the same compilation unit as the
class implementation:

(code like this has been presented in the book)

// DerivedType.cpp
// DerivedType is the type we want to register, and it is derived from
BaseType
namespace {
BaseType *CreateDerivedTypeObject() { return new DerivedType; }
const bool registered = MyFactory::Instance().Register("DerivedType",
CreateDerivedTypeObject);
}

MyFactory is:
typedef Loki::SingletonHolder<Loki::Factory<BaseType, std::string> >
MyFactory;

Now, in the client code I only use the base class interface, like:

BaseType *object = MyFactory::Instance().CreateObject("DerivedType");

This works, for example, if I'd compile the library (which contains the base
class, derived classes
and factory) to be a dynamically loaded one, since all translation units in
the library will be included.

But if I compile to a static library, the linker won't see any of the
derived classes being used (implicitly)
and will drop them from the final module.

Currently, I have implemented a hack solution - to register all derived
classes in a centralized
place (for example a static method BaseType::RegisterAllDerived()).. but as
you can see, it's not
very pretty.

I found no way to tell the linker to link with all objects in the library,
except by specifying
the objects outside the library - therefore not using a library (I am using
VC++7.1).

I understand that this isn't a serious issue, since in a library there can
be a only a finite amount
of types to register... But it seems too hacky.

Any insight about this?

PS. This linker optimization has other consequences, for example dropping
win32 resource objects
in a static library.
 
L

lilburne

adeht said:
I understand that this isn't a serious issue, since in a library there can
be a only a finite amount
of types to register... But it seems too hacky.

Any insight about this?

A similar problem can occur with persistent classes. The
application may have no direct knowledge of all the derived
classes using only the base class directly in the code.

We have a perl script that zips through all the headers
looking for classes that are derived from Base. It then
creates a file containing a function that 'uses' all the
classes and a call such that the linker requirements are
satisfied. I can't recall the details as this magic has
worked for the last 8 years, but the file looks something like:

// This file is auto-generated DO NOT modify

#include "derived1.h"
#include "derived2.h"
#include "derivedN.h"

bool derived_linker_loader(bool initialise)
{
if (initialise) {
static derived1* d1 = new derived1;
delete d1;
static derived1* d2 = new derived2;
delete d2;
static derivedN* dN = new derivedN;
delete dN;
}
return !initialise;
}

then in the persistence subsystem there is the call

derived_link_loader(false);

the script is run after all code updates before compilation
and linking.

HTH
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,040
Latest member
papereejit

Latest Threads

Top