Question

I have a configuration that has a library and a console application. They are pretty barebones at the moment. I am using Visual Studio 2010 and the library and console application are both statically linked to the Runtime. The console application also links to the library.

In the library, I can add this code in a source file:

class MyClass
{
public:
    MyClass()
    {
        printf("MyClass loaded\n");
    }
};

class MyClass2
{
public:
    static MyClass my_class;
};

MyClass MyClass2::my_class;

Now, my understanding is that my_class should be initialized at some point before main(). However, it never happens (as I do not get the printed message).

I can, however, get it to initialize using two different methods:

  1. Put the code in the console application instead. Doing that will invoke the printf() statement for certain.
  2. Modify MyClass2 to include a static function that is called from a global variable in the library and use that global variable in main() in the console application.

Example for #2 above:

Library file:

class MyClass
{
public:
    MyClass()
    {
        printf("MyClass loaded\n");
    }
};

class MyClass2
{
public:
    static MyClass my_class;
    static int Ping();
};

MyClass MyClass2::my_class;
int my_global = MyClass2::Ping();

Console application file:

extern int my_global;
int main()
{
    printif("%d", my_global);
}

Is Windows trying to help me by delay loading the linked in library's static variables?? Or is there some compiler setting I have set? This behavior was totally unexpected by me.

Was it helpful?

Solution

Is the "library file" part of the final executable. If it is an object file in a statically linked library, it will only be part of the final executable if it resolves an otherwise unresolved external symbol. (This is the definition of a library.) If you never use any symbol in the object file, it won't be part of your executable, and it's as if the source file wasn't part of the application.

If the library is dynamically loaded, the situation is slightly different; a .dll is loaded as a unit (and not object file by object file, so it's not really a library), but if there are no unresolved symbols which would be resolved by loading the DLL, it won't be loaded either.

What you probably want to do is link against the object files, and not against a library. In Visual Studios, this means putting all of the sources in the same project. Or... you can link the library as a .dll, and then explicitly load it using LoadLibrary. (This is what we do for libraries which are only referenced because they have constructors of static objects which register themselves.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top