gpt4 book ai didi

c++ - 共享库的静态库中静态变量的单独实例

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:50:02 27 4
gpt4 key购买 nike

考虑以下由两个共享库组成的设置,它们都使用静态库:

static.cpp

#include "static.h"
static int a = 0;
int getA()
{
return a++;
}

static.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 的两个实例,每个共享库一个?

最佳答案

Apparently, despite the static keyword in front of a in static.cpp, only one instance of a exists.

那是不正确:a 存在两个实例,但实际只使用了一个。

之所以发生,是因为(与您的预期相反)printB 调用了第一个 getA 可用(来自 libshareda.so 的那个,而不是来自 libsharedb.so 的那个)。这是 UNIX 共享库和 Windows DLL 之间的一个主要区别。 UNIX 共享库模拟如果您的链接是:

clang++  -L. -o main main.cpp shareda.o sharedb.o libstatic.a

那么你能做些什么来“解决”这个问题呢?

  1. 您可以使用 -Bsymbolic 链接 libsharedb.so 以更喜欢它自己的 getA
  2. 您可以将 getA 完全隐藏在 libsharedb.so 中(就像它是私有(private)实现细节一样):

    clang++ -c -fvisibility=hidden -fPIC static.cpp
    ar rcs libstatic.a static.o
    clang++ -shared -o libsharedb.so sharedb.o libstatic.a

  3. 您可以使用链接器版本脚本获得类似的结果。

附言您的链接命令:

clang++  -L. -lshareda -lsharedb -o main main.cpp

完全倒退。应该是:

clang++  -L. -o main main.cpp -lshareda -lsharedb

源/目标文件和库在命令行上的顺序 matters ,并且库应该遵循引用它们的目标文件。

关于c++ - 共享库的静态库中静态变量的单独实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34381562/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com