C++ 共享库的静态库中静态变量的单独实例
考虑以下由两个共享库组成的设置,它们都使用静态库: 静态.cppC++ 共享库的静态库中静态变量的单独实例,c++,linux,shared-libraries,clang,static-libraries,C++,Linux,Shared Libraries,Clang,Static Libraries,考虑以下由两个共享库组成的设置,它们都使用静态库: 静态.cpp #include "static.h" static int a = 0; int getA() { return a++; } #include <iostream> #include "shareda.h" #include "static.h" void printA() { std::cout << getA() << std::endl; } #include &l
#include "static.h"
static int a = 0;
int getA()
{
return a++;
}
#include <iostream>
#include "shareda.h"
#include "static.h"
void printA()
{
std::cout << getA() << std::endl;
}
#include <iostream>
#include "sharedb.h"
#include "static.h"
void printB()
{
std::cout << getA() << std::endl;
}
#include "shareda.h"
#include "sharedb.h"
int main()
{
printA();
printA();
printB();
printA();
printB();
return 0;
}
静态.h
#pragma once
int getA();
#pragma once
void printA();
#pragma once
void printB();
shareda.cpp
#include "static.h"
static int a = 0;
int getA()
{
return a++;
}
#include <iostream>
#include "shareda.h"
#include "static.h"
void printA()
{
std::cout << getA() << std::endl;
}
#include <iostream>
#include "sharedb.h"
#include "static.h"
void printB()
{
std::cout << getA() << std::endl;
}
#include "shareda.h"
#include "sharedb.h"
int main()
{
printA();
printA();
printB();
printA();
printB();
return 0;
}
sharedb.cpp
#include "static.h"
static int a = 0;
int getA()
{
return a++;
}
#include <iostream>
#include "shareda.h"
#include "static.h"
void printA()
{
std::cout << getA() << std::endl;
}
#include <iostream>
#include "sharedb.h"
#include "static.h"
void printB()
{
std::cout << getA() << std::endl;
}
#include "shareda.h"
#include "sharedb.h"
int main()
{
printA();
printA();
printB();
printA();
printB();
return 0;
}
main.cpp
#include "static.h"
static int a = 0;
int getA()
{
return a++;
}
#include <iostream>
#include "shareda.h"
#include "static.h"
void printA()
{
std::cout << getA() << std::endl;
}
#include <iostream>
#include "sharedb.h"
#include "static.h"
void printB()
{
std::cout << getA() << std::endl;
}
#include "shareda.h"
#include "sharedb.h"
int main()
{
printA();
printA();
printB();
printA();
printB();
return 0;
}
我使用以下命令编译并运行了这些文件(使用clang3.8.0,从源代码编译,以及使用gnuld2.25的64位Debian):
令我惊讶的是,结果如下:
0
1
2
3
4
我的期望是:
0
1
0
2
1
显然,尽管static.cpp中a
前面有static
关键字,但只存在a
的一个实例。有没有办法让a
有两个实例,每个共享库一个
显然,尽管static.cpp中的a前面有static关键字,但只存在a的一个实例
这是不正确的:存在两个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
源/对象文件和库在命令行上的顺序,库应遵循引用它们的对象文件 对于静态库,我会像预期的那样工作。msvc下的行为正好相反,我正在尝试获得您得到的结果(使用相同的静态访问对所有DLL和exe进行相同的函数调用)。现在运气不好,你能告诉我怎么得到它吗?