共享库的静态库中静态变量的单独实例
Separate instance of static variable in static library for shared library
考虑以下由两个共享库组成的设置,这两个库都使用静态库:
静态.cpp
#include "static.h"
static int a = 0;
int getA()
{
return a++;
}
静态.h
#pragma once
int getA();
shareda.cpp
#include <iostream>
#include "shareda.h"
#include "static.h"
void printA()
{
std::cout << getA() << std::endl;
}
shareda.h
#pragma once
void printA();
sharedb.cpp
#include <iostream>
#include "sharedb.h"
#include "static.h"
void printB()
{
std::cout << getA() << std::endl;
}
sharedb.h
#pragma once
void printB();
main.cpp
#include "shareda.h"
#include "sharedb.h"
int main()
{
printA();
printA();
printB();
printA();
printB();
return 0;
}
我用以下命令编译并运行了这些文件(使用Clang 3.8.0,从源代码编译,使用GNU ld 2.25的64位Debian):
clang++ -c static.cpp -o static.o -fPIC
ar rcs libstatic.a static.o
clang++ -c shareda.cpp -o shareda.o -fPIC
clang++ -shared -o libshareda.so shareda.o libstatic.a
clang++ -c sharedb.cpp -o sharedb.o -fPIC
clang++ -shared -o libsharedb.so sharedb.o libstatic.a
clang++ -L. -lshareda -lsharedb -o main main.cpp
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./main
令我惊讶的是,输出如下:
0
1
2
3
4
我的期望是:
0
1
0
2
1
显然,尽管static.cpp中a
前面有static
关键字,但a
只存在一个实例。有没有办法拥有两个a
实例,每个共享库一个?
显然,尽管static.cpp中的前面有static关键字,但只有一个实例存在。
这是不正确的:存在两个a
实例,但实际只使用了一个。
而发生是因为(与您的预期相反)printB
调用第一个可用的getA
(来自libshareda.so
的,而不是来自libsharedb.so
的)。这是UNIX共享库和Windows DLL之间的一个主要区别。UNIX共享库模拟了如果您的链接是时会发生的情况
clang++ -L. -o main main.cpp shareda.o sharedb.o libstatic.a
那么,你能做些什么来"修复"这个问题呢?
- 您可以使用
-Bsymbolic
将libsharedb.so
链接为自己的getA
您可以将
getA
完全隐藏在libsharedb.so
中(就好像它是一个私有的实现细节一样):clang++ -c -fvisibility=hidden -fPIC static.cpp ar rcs libstatic.a static.o clang++ -shared -o libsharedb.so sharedb.o libstatic.a
- 使用链接器版本脚本可以获得类似的结果
附言:你的链接命令:
clang++ -L. -lshareda -lsharedb -o main main.cpp
完全倒退了。应该是:
clang++ -L. -o main main.cpp -lshareda -lsharedb
命令行中源/对象文件和库的顺序很重要,库应该遵循引用它们的对象文件。
相关文章:
- C++两个源文件之间共享的枚举的静态实例
- 宏为模板类静态实例生成有效的标识符
- 我可以在类头文件中定义一个类的const静态实例吗
- 类的静态实例不能调用私有成员函数.C++
- 第二个dll中的静态实例的破坏者未被调用
- 类的静态实例无法在程序退出时正确处理资源删除
- C++:外部类中内部类的静态实例
- 结构定义包含自身的静态实例
- 什么是C++中C#静态实例的等价物
- 父类包含子类C++的静态实例
- 在C++中创建静态实例的未解析外部
- 多个对象的静态实例变量-c++
- 在c++中,一旦程序退出,singleton(静态实例)就会被销毁,这是正确的原因
- 对从静态实例引用的类模板的静态成员的未定义引用
- 在类自身内部创建类的静态实例的正确方法
- 初始化模板类中嵌套类的静态实例
- 卸载c++插件中的静态实例变量
- 在c++ STL类型的静态实例上使用OpenMP threadprivate指令
- 我的类的静态实例函数不像我预期的那样工作
- 保留子类的中心列表,但避免静态实例