【问题标题】:Constructor of static variable inside shared library共享库中静态变量的构造函数
【发布时间】:2016-06-23 06:52:15
【问题描述】:

我很好奇在共享库中实例化的静态变量是否被实例化了。 首先,代码如下:

AClass.h

class A {
  public:
    A(int x) { cout << "A constructor called." << endl; }
};

MyLib.cpp

#include "AClass.h"

static A StaticVariableA(50);

所以,有了这段代码加上一个 Main.cpp 文件(只有一个空的 main 函数),我想通过 中的变量的初始化来调用构造函数MyLib.cpp.

我将 MyLib.cpp 编译为一个共享库,并通过多种方式将主程序链接到它,但均未成功。鉴于这两个文件已经编译为目标文件:

(first compiled MyLib.cpp to a shared library)
$ g++ -O0 -fPIC -shared -Wl,-soname,libMyLib.so -o libMyLib.so MyLib.o

(Tried to link the two files)
$ g++ -O0 Main.o -rdynamic libMyLib.so -Wl,-rpath,./
$ g++ -O0 Main.o -L . -Wl,-rpath,./ -lMyLib

到现在都没有成功,请问:这可能吗?如果不可能,为什么?共享库中如何处理静态变量? (我主要对Linux机器感兴趣)

(我知道我不应该使用这样的共享库。但我只是想知道它不起作用)

奇怪的是,this code 有效。将库 GMLOSStFeatEx(使用/src/FeatureExtractor/ 文件编译的共享库)链接到/tools/Dummy.cpp 时。它调用RegisterStaticFeature类型的静态变量的构造函数。

编辑

好像@Pupsik 说的,它正在被优化。但是,我上面链接的代码没有得到优化。它也没有任何被外部代码调用或引用的函数。

this 问题中,它建议使用链接器标志-no-as-needed,它可以工作。但是正如下面可以看到的那样,编译我提到的the code时没有这样的标志。

/usr/bin/c++   -O0 -g -I/usr/local/include  -fPIC -fvisibility-inlines-hidden 
-Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual 
-Wno-missing-field-initializers -pedantic -Wno-long-long 
-Wno-maybe-uninitialized -Wnon-virtual-dtor -Wno-comment -std=c++11 -g
-fno-exceptions -fno-rtti  -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS 
-D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -L/usr/local/lib     
CMakeFiles/Dummy.dir/DummyMain.cpp.o  -o Dummy -rdynamic ../src
/FeatureExtractor/libGMLOSStFeatEx.so ../src/FeatureExtractor
/libGMLOSDynFeatEx.so ../src/Support/libGMLOSCfgPrinter.so 
-lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMX86Desc -lLLVMX86Info 
-lLLVMMCDisassembler -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMCodeGen 
-lLLVMScalarOpts -lLLVMProfileData -lLLVMInstCombine -lLLVMInstrumentation 
-lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMIRReader -lLLVMAsmParser 
-lLLVMTransformUtils -lLLVMipa -lLLVMMCJIT -lLLVMExecutionEngine -lLLVMTarget 
-lLLVMAnalysis -lLLVMRuntimeDyld -lLLVMObject -lLLVMMCParser -lLLVMBitReader 
-lLLVMMC -lLLVMCore -lLLVMSupport -lpapi -lrt -ldl -ltinfo -lpthread -lz -lm 
-Wl,-rpath,/path-to-gmlos/build/src/FeatureExtractor:/path-to-gmlos/build/src/Support

【问题讨论】:

  • 什么是static global 变量?它要么是静态的,要么是全局的。此外,如果这是在 cpp 文件中:static A StaticVariableA(50); 该变量仅在该模块中已知,其他没有。它不是全局变量。
  • 哦,是的。对于那个很抱歉。事实上,它不能同时是静态的和全局的。这是关于静态变量的。
  • 也许您的 MyLib.cpp 已被编译器优化,因为没有找到对该库的引用?尝试在 MyLib.cpp 中添加一些虚拟函数并从 main.cpp 调用它
  • @Pupsik 似乎是这样。但这很奇怪。为什么this 没有得到优化?它没有任何外部引用的函数。

标签: c++ constructor shared-libraries static-variables


【解决方案1】:

所以,事实证明@Pupsik 是完全正确的!顺便说一句,谢谢。

正如他所说,图书馆正在被优化:

也许您的 MyLib.cpp 已被编译器优化,因为没有找到对该库的引用?尝试在 MyLib.cpp 中添加一些虚拟函数并从 main.cpp 调用它

我引用的 github 上的代码没有得到优化,因为该库中确实有一个被 main 函数调用的函数。

我找到的解决方案是使用链接器标志-as-needed。它无论如何都会链接库,因此不会从二进制文件中取出。

所以,这清除了一切。 再次感谢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    • 1970-01-01
    相关资源
    最近更新 更多