I've compiled a static library which contains classes for all kinds of services.
Some of these service need initialisation which I'd like to be performed automatically.
For this purpose I have added a class to
my library which does these initialisations
in its ctor. In the implementation file of
this class a create a single static instance of it.
I've added the library to one of my projects. To my surprise, the initialisation does not take place since the static instance of my initialiser class
is not being created.
Is that normal behaviour for static objects in libraries which are not being referenced from anywhere in the code ?
To my knowledge the term "static library" does not exist on the win32 platform. The object code of a .dll is never linked to the code of the excutable (only the .lib stub is linked). Please enlighten my on how can I produce a .lib file containing my object code without a .dll - Thanks in advance.
To your problem now. Your approach is correct and I have also used it several times to do just what you are describing.
Including the above code fragment in a library will make the InitClass constructor to be called right after the .dll is mapped into your process' address space (after it gets loaded).
If the executable does not reference any of the symbols contained in the .dll, the linker may NOT link the .dll to your executable (depends on the compiler, build options etc.). You need to reference at least one symbol (variable, class, function) exported from your library, or load the .dll explicitly by using the LoadLibrary() call. The latter will also force the initialization of any statically declared variables or class instances.
Regards,
--harizak
P.S. The abovementioned problem can only be experienced in the win32 platform, since most unices I've been working on link the shared object unconditionally.
it is definitly possible to build and use
static libraries on win32. I have so dozens of times.
To point you to 2 things:
(Assuming you are using VC++ 6)
a) static lib projects
Select File->New->Projects->Win32 Library(static)
This will create a project for a Win32 static
library. (in the same dialog you may choose to create a dll project)
b) Different Ways of using the runtime libraries
-Open the settings of an executable project.
-Select the C++ Tab.
-Select the Category 'Code Generation'
-Check the different runtime libraries you can link to.
You will see that there exist single- and multithreaded builds, release- and debugbuilds and (Important!) dll and static versions of the runtime libraries.
Hope this info is helpful for you.
Anyways ... still looking for an answer to my problem :-(
Thanks for the info. However I do not use the IDE. Is it possible for you to send me the command line used to create a static library?
Based on my experience with the Win32 platform the term static refers to the C runtime that will be linked to the created library, not the type of the library being built.
Do you say for example that after you create a static library you don't have a .dll file created? I mean that if the .dll file does get created, then it is NOT a static library!
To your problem now. Are you a 100% sure that the .lib is linked to your executable? Use the depends.exe tools to verify. If not this is your problem: Try loading the .dll file explicitly using the LoadLibrary() call and the static classes in the .dll will get initialized. Otherwise I need to see some code. I would also suggest you try something really simple - a library will a single class such as the one contained in my previous post.
To be honest this close to what I've been doing sometime: renaming the XX.obj object file to XX.lib. The .lib and .obj extensions for the VC compiler seem to be the same.
In your problem now. From the 2 bullets/comments regarding the behavior of your exe, it seems that if you use this way or another the class from the library its static member gets initialized otherwise not. This simply means that the linker avoids linking your executable with the lib since no references to it are found.
Compare the size of your exe with and without linking the .lib - given that you don't instanciate explicitly the "offending" class. I believe that the size will be in both cases the same.
In order to maintain unreferced symbols during the link phase, pass the option /OPT:NOREF to the linker. Command line should look like:
It was my guess, too, that the linker
removes unreferenced objects. I came across that linker setting yesterday (/OPT:NOREF) but to my disappointment it
didn't and doesn't solve my problem
Try building the library containing the static class instance as a DLL. Then through main() attempt to load it using the LoadLibrary() call. What happens?
Well to my knowledge if you declare an object outside of any function body or class declaration like...
Code:
CSomeClass MyClassObj;
Its declared at global scope, and is called global object. You dont need to decalre it with static keyword. I guess in C, if you want to limit the scope of a var, you declare it with static (even though a class is meaning-less to C) may be using static limits the visibility of the obj somehow. But then the compiler would have complained.
But i dont think C++ standard different set of rules for lib or main programs.
Regards,
Usman.
I am affraid I cannot help uless you post some code. Try to reduce the problem as much as possible and then post the executable's as also the static lib's code.
Have you attempted to build the lib as dynamic and then load it by calling the LoadLibrary() function? This will definitly force yout static instance to be loaded and initialized ...
I can confirm that the instance is being created when compiling the library as a dll.
Sadly, thats not really a solution for me.
I'd really like to know if the problems I am
experiencing are standard behaviour, that
is if other compilers/linkers produce the same result.
Personally I doubt that it is a valid linker decision to eleminate code that 'normally'
would be executed during the construction of a static global object on
app launch.
Hi again. Unfortunately but what you are trying to do seems not to be possible when your library is statically linked to your executable.
Find attached an example, along with a README file, on how to force the linker to include a non-referenced symbol in the output executable. Not a very convenient way though, since the name of the symbol needs to be known a-priori (using the dumpbin.exe /symbols xxx.lib) in order to include it during the link.
Note also that the static does not apply in your case since external linkage is required for symbols that have to be mapped to your executable initialized data segment.
If I find a more elegant solution I'll let you know ...
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.