Reputation: 1563
I have a static factory that relies on a static member of itself to register the class into the factory system.
class Foo_A_Maker : public FooFactory<Foo, const std::string &>
{
private:
// Register this as a type using a static instance of itself.
// This is really the only time it is created. That's why the
// constructor is private.
Foo_A_Maker() : FooFactory("Foo_A") {}
static const Foo_A_Maker registerThis;
public:
virtual std::shared_ptr<Foo> MakeProduct(const std::string& params) const;
};
This has worked for years in all my projects, but now I have added it to a static library. In the static library, the ctor is never called and the object never registers. If I put this code in the exe project it works again. I have determined that this is not linking by introducing a link time error.
Am I missing something? Can I force a link? And if I use this across compilation boundaries can the EXE project add its own factories?
Thanks all.
Upvotes: 2
Views: 1144
Reputation: 31931
A static member variable in the class definition needs to be matched with the same variable outside of that class (I'm not clear on the exact terms for each part of this). That means in some CPP file, outside of the class, you need to write this:
Foo_A_Maker Foo_A_Maker::registerThis;
This is the point at which the object is created (that it works in any program without this is a bit strange). Place this inside one of the CPP files and you should be alright.
You should also just be able to put this inside a CPP file without declaring it as a static member in the class. This would be the easier route. That is, remove the static and just put this in a CPP file:
Foo_A_Make registerThis;
Upvotes: 0
Reputation: 91300
This is how libs are supposed to work - the linker only takes the symbols it needs (referenced from the outside). The correct way of solving this is to provide an init function.
For Visual Studio you can find the exact symbol name that you need, and pass /INCLUDE
as a command-line option to the linker. You can try with /OPT:NOREF
- it sounds like it could work, but haven't tested it.
Upvotes: 1