首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >共享库静态库中静态变量的分离实例

共享库静态库中静态变量的分离实例
EN

Stack Overflow用户
提问于 2015-12-20 13:38:15
回答 1查看 1.1K关注 0票数 1

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

static.cpp

代码语言:javascript
复制
#include "static.h"
static int a = 0;
int getA()
{
    return a++;
}

static.h

代码语言:javascript
复制
#pragma once
int getA();

shareda.cpp

代码语言:javascript
复制
#include <iostream>
#include "shareda.h"
#include "static.h"
void printA()
{
    std::cout << getA() << std::endl;
}

shareda.h

代码语言:javascript
复制
#pragma once
void printA();

sharedb.cpp

代码语言:javascript
复制
#include <iostream>
#include "sharedb.h"
#include "static.h"
void printB()
{
    std::cout << getA() << std::endl;
}

sharedb.h

代码语言:javascript
复制
#pragma once
void printB();

main.cpp

代码语言:javascript
复制
#include "shareda.h"
#include "sharedb.h"
int main()
{
    printA();
    printA();
    printB();
    printA();
    printB();
    return 0;
}

我使用以下命令编译和运行这些文件(使用从源代码编译的Clang 3.8.0和使用GNU 2.25的64位Debian ):

代码语言:javascript
复制
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

令我惊讶的是,产出如下:

代码语言:javascript
复制
0
1
2
3
4

我的期望是:

代码语言:javascript
复制
0
1
0
2
1

显然,尽管static关键字在static.cpp中的a前面,但a只有一个实例。是否有一种方法可以拥有两个a实例,一个用于每个共享库?

EN

回答 1

Stack Overflow用户

发布于 2015-12-20 15:57:16

显然,尽管在static.cpp中有一个静态关键字,但只有一个实例存在。

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

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

代码语言:javascript
复制
clang++  -L. -o main main.cpp shareda.o sharedb.o libstatic.a

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

  1. 通过使用libsharedb.so,可以链接getA以更好地使用自己的getA
  2. 您可以将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
  3. 您可以使用链接器版本脚本实现类似的结果。

你的链接命令:

代码语言:javascript
复制
clang++  -L. -lshareda -lsharedb -o main main.cpp

完全向后。它应该是:

代码语言:javascript
复制
clang++  -L. -o main main.cpp -lshareda -lsharedb

命令行B.事项上源/对象文件和库的顺序,库应该遵循引用它们的对象文件。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34381562

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档