Global and file-static variables in static library
In some code I wrote for a client, I use the "self-registering plugin
pattern:
// D1.h
class D1: public Base
{
public:
D1();
// declare virtual overrides
};
//--------------------------------------------------
// D1.cpp
#include "D1.h"
namespace
{
Base* Create(){return new D1;}
bool auto_register = RegisterPlugin("D1", Create);
}
D1::D1(){}
// virtual function definitions for D1
//--------------------------------------------------
The function RegisterPlugin() creates an entry in a map of strings to
function pointers, which allows a factory function to create an instance
of the plugin D1 from its name "D1". The key feature of the pattern is
that the file D1.h is not #include'd anywhere except D1.cpp. It works
despite the fact that the code in D1.cpp is superficially not used by
the rest of the program. It works on VC7.1 and VC8 and various
unix/linux compilers.
Recently, however, using VC8, the client got it into his head to compile
my code into a static library (.lib) before linking it to his code. And
now the pattern does not work any more (the map is not populated).
Initially I thought this might be because I placed the code in an
anonymous namespace ("file-static"), but the same thing happens if I
make auto_register a global variable (using a different name for each
plugin).
It seems that when a .obj file is embedded in a static library, and then
linked with a client program such that the content of that .obj is
apparently unused, the content of that .obj file is not contained in the
image. This does not happen if the .obj files are linked individually.
Why does this happen? And what should I do about it? [I have found a
couple of workarounds, but they require explicit reference to something
in the plugin implementation, which rather spoils the beauty of the
pattern.]
--
David Wilkinson
Visual C++ MVP