7

I am working on a factory that will have types added to them, however, if the class is not explicitly instiated in the .exe that is exectured (compile-time), then the type is not added to the factory. This is due to the fact that the static call is some how not being made. Does anyone have any suggestions on how to fix this? Below is five very small files that I am putting into a lib, then an .exe will call this lib. If there is any suggestions on how I can get this to work, or maybe a better design pattern, please let me know. Here is basically what I am looking for

1) A factory that can take in types

2) Auto registration to go in the classes .cpp file, any and all registration code should go in the class .cpp (for the example below, RandomClass.cpp) and no other files.

BaseClass.h : http://codepad.org/zGRZvIZf

RandomClass.h : http://codepad.org/rqIZ1atp

RandomClass.cpp : http://codepad.org/WqnQDWQd

TemplateFactory.h : http://codepad.org/94YfusgC

TemplateFactory.cpp : http://codepad.org/Hc2tSfzZ

3 Answers 3

8

When you are linking with a static library, you are in fact extracting from it the object files which provide symbols which are currently used but not defined. In the pattern that you are using, there is probably no undefined symbols provided by the object file which contains the static variable which triggers registration.

Solutions:

  • use explicit registration
  • have somehow an undefined symbol provided by the compilation unit
    • use the linker arguments to add your static variables as a undefined symbols
    • something useful, but this is often not natural
    • a dummy one, well it is not natural if it is provided by the main program, as a linker argument it main be easier than using the mangled name of the static variable
  • use a linker argument stating that all the objects of a library have to be included
  • dynamic libraries are fully imported, thus don't have that problem
Sign up to request clarification or add additional context in comments.

3 Comments

"dynamic libraries are fully imported, thus don't have that problem". I tried this with a .dll and still got this issue. Do you know why that may be?
Non -- but then I've never pretended to be knowledgeable about Windows.
@jack: In a DLL, the problem is most likely not that the registration functions didn't run, but that they updated a registration list which is private to the DLL. For this to work, the main application needs to query the registration list of the DLL rather than maintaining its own list.
6

As a general rule of thumb, an application do not include static or global variables from a library unless they are implicitly or explicitly used by the application.

There are hundred different ways this can be refactored. One method could be to place the static variable inside function, and make sure the function is called.

2 Comments

Is there any sort of automatic registration, like I am doing, that will work?
Not 100% automatic, but it will work if you, somehow, would add a reference to the static variable from any code or variables that are included in the application.
2

To expand on one of @AProgrammer's excellent suggestions, here is a portable way to guarantee the calling program will reference at least one symbol from the library.

In the library code declare a global function that returns an int.

int make_sure_compilation_unit_referenced() { return 0; }

Then in the header for the library declare a static variable that is initialized by calling the global function:

extern int make_sure_compilation_unit_referenced();
static int never_actually_used = make_sure_compilation_unit_referenced();

Every compilation unit that includes the header will have a static variable that needs to be initialized by calling a (useless) function in the library.

This is made a little cleaner if your library has its own namespace encapsulating both of the definitions, then there's less chance of name collisions between the bogus function in your library with other libraries, or of the static variable with other variables in the compilation unit(s) that include the header.

1 Comment

This is the first suggestion I've found that actually works, so thanks for that. The downside is that you need to #include the header file from the library in your main executable to ensure the code links, which means you need to know all the library headers at compile time. Still, it's something.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.