C++ global variable not initialized when linked through static libraries, but OK when compiled with source

后端 未结 2 1201
感情败类
感情败类 2020-12-13 14:21

I have created a system that automatically registers function objects (functors) into a map based on the constructor of an global instance.

In each cpp file that def

相关标签:
2条回答
  • 2020-12-13 14:50

    I believe your object file from the library is not getting linked. Look how Microsoft handles the acrtused symbol (search case insensitive, I do not remember the case and there's no MSVC on this machine).

    Once you know how they handle acrtused, do the same thing with your global variable to force it to get linked.

    Will update if I find the answer.

    Here are a couple of possibilities to force things to link and initialize in a somewhat forced order.

    Look here for a GCC answer.

    Look here for MSVC10.

    0 讨论(0)
  • 2020-12-13 15:07

    Short answer for android NDK work, any static libs that are affected by this problem should be added to the LOCAL_WHOLE_STATIC_LIBRARIES variable -- they'll then be referenced using the -Wl,--whole-archive flag and won't be subject to stripping.

    Longer answer for MSVC:

    Static variables in a translation unit are initialized before any regular code in the translation unit executes. In practice the initialization happens when the containing executable or dynamic library is loaded. When your \c main() is called, or your call to LoadLibrary()/dlopen() completes, any static variables will have been initialized.

    The Problem, as described by MSDN:

    Constructors and assignment by global function or static methods in the declaration do not create a reference and will not prevent /OPT:REF elimination. Side effects from such code should not be depended on when no other references to the data exist.

    It can be convenient to place the object code from multiple translation units in a single file, a static library conventionally named with a \c .lib or \c .a suffix. The MSVC linker does dependency analysis on static libraries and will not include code that is not referenced by the including entity.

    The common pattern of using a static variable to declare and cause the registration of a factory object can fail in this circumstance -- the MSVC linker deems the static as being unreachable and strips it from the result.

    Solutions

    A useful google search: http://www.google.com/search?q=msvc+factory+static+library

    One solution is to set the /OPT:NOREF linker flag on the including entity. However, this is an all or nothing setting, and will require that all included libraries be fully linkable.

    If something in the file containing the static is referenced (directly or indirectly) by the including entity, then by the language rules the static itself must be preserved.

    The most basic approach is to put a dummy function in the file, and reference that from somewhere known to be considered reachable.

    Another approach is to use the /INCLUDE linker flag to reference an entity in the problem file. Assuming an entity named DummyForLinkProblem, this can be done in the including entity's source:

    #pragma comment(linker, "/include:DummyForLinkProblem")
    

    ZooLib's Solution

    ZooLib entities currently affected by this problem are those in ZFile_Win.cpp, ZGRgnRep_HRGN.cpp, ZNet_Internet_WinSock.cpp, ZStreamRWCon_SSL_Win.cpp, ZTextCoder_Win.cpp and ZUnicode_Normalize_Win.cpp.

    We #include ZCompat_MSVCStaticLib.h in the corresponding header files, and put in each a ZMACRO_MSVCStaticLib_Reference(ModifiedFileName). In the cpp files we put a ZMACRO_MSVCStaticLib_cpp(ModifiedFileName). The ModifiedFileName is generally the filename with the leading Z and file extension removed, the same style as used in ZCONFIG_API_XXX macros.

    To ensure that your executable or library does not strip these entities, simply #include the appropriate header file from known referenced code in your including entity. This will cause a non-executing reference to occur, and things will work as expected.

    0 讨论(0)
提交回复
热议问题