【发布时间】:2019-10-13 21:25:42
【问题描述】:
我有一些无法更改或重建的静态库。该库使用全局变量。像这样的:
//lib A
#include <iostream>
static int i = 0;
void printA(){
std::cout << i++ << std::endl;
}
我想创建两个共享库,它们拥有自己的静态库“副本”及其全局状态:
//lib B
#include "liba.h"
void printB(){
printA();
}
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
//lib C
#include "liba.h"
void printC(){
printA();
}
...同时使用它们:
#include "libb.h"
#include "libc.h"
int main(){
printB();
printB();
printC();
printC();
}
我希望得到以下输出:
0
1
0
1
.. 但实际上得到:
0
1
2
3
似乎libB 和libC 共享公共计数器变量。如果可以访问libA 源代码,我将使用-fvisibility=hidden 重新构建它。但不幸的是我只有二进制。
是否有任何方法可以在不重建 libA 的情况下实现预期行为?
【问题讨论】:
-
If had access toI have only binary.- 所以你是否可以访问libA.a?您可以将libA.a解压缩为.o文件,然后使用 ex 重命名 all 符号。objcopy --redefine-sym printA=printAcopy,然后重建libAcopy.a,然后从printC()调用printAcopy-printC() { printAcopy(); }。 -
将您的库副本放在单独的命名空间中。或者,围绕静态库构建一个包装共享对象。包装器将所有符号设为私有,并且仅导出具有不同名称的感兴趣的函数。
-
两个库是分开链接的吗?
-
@KamilCuk,是的,我有
libA.a,但我不想改变它。因为它可能会更新一次。 -
不应该用“Linux”来标记吗?因为共享库的行为在 Linux 和 Windows 之间有所不同。在 Windows 下,共享库 (dll) 将拥有自己的这些全局变量版本,正如 OP 所期望的那样。