假设我有库(A)
实现单例模式(它的实现中有一个静态变量)。
(A)
库被编译为静态库。
现在,让我们说一下我的问题:
(B)
,另一个静态库,与(A)
静态链接。 (C)
,另一个静态库,与(A)
静态链接。 (D)
,一个与(B)
和(C)
相关联的顶级程序。最后,我的单身人士真的是单身人士(我的变量真的是静态的)吗? (B)
和(C)
是否从(A)
获取相同的静态变量(它是unic)吗?或者(A)
是否静态链接了两次嵌入式(A)
代码的事实两次以最终二进制代码中出现两次(A)
的静态变量结束?然后,如果(B)
修改了静态变量值,(C)
将无法看到更改?
注意:我在更改要静态链接而不是动态链接的项目库时遇到过这种情况。我只是想知道我是否做错了什么,或者这是否是一种正常的已知行为。
答案 0 :(得分:7)
首先:
(B)和(C)不与(A)相关联。静态库是编译的,而不是链接的。 构建(B)和(C)时,编译器可能需要查看(A)中的某些定义,但不要将其与链接混淆。 (A)代码不会复制到(B)或(C)。
<强>其次:强>
(D)必须与(A),(B)和(C)联系。这意味着您只能在(D)中获得(A)代码的一个副本。
动态链接库/共享对象:
如果(B)和(C)是dlls / sos,那当然会有所不同。 Dll是链接的,因此如果您将(B)和(C)构建为dll并将它们链接到(A),那么您将在(B)和(C)中分别使用(A)代码的副本。
(B)和(C)是否从(A)
中获得相同的静态变量
这取决于您的变量是否有external or internal linkage。以下头文件包含带有内部链接的静态int变量。这意味着包含此文件的每个翻译单元都将获得它自己的myVariable
。
//MyHeader.h
#pragma once
static int myVariable = 0;
答案 1 :(得分:0)
静态链接库,与静态变量无关。
静态变量在当前编译范围之外是不可见的(在.o文件中没有创建符号名称,因此没有其他.o文件可以通过符号名称找到该变量。)
这意味着变量
static int foo;可以存在于每个编译范围中,每个编译范围都是唯一的
答案 2 :(得分:0)
您的静态变量实际上是静态的。我怀疑,即使(B)链接(A),(B)没有拿起它自己的(A)副本 - 而是包含(A)应该链接的信息。
然而,可以在两个库中使用静态变量编译相同的源代码 - 例如:
TEST.CPP:
int g_myGlobal = 23;
并在(A)和(B)静态库中编译它,但是当链接整个应用程序或dll时 - 你会得到关于双重定义的静态变量的链接器错误。
但是,如果使用static关键字声明变量:
TEST.CPP:
static int g_myGlobal = 23;
然后,如果从(A)和(B)链接相同的源代码 - 它将被编译并链接好,但结果你将有两个g_myGlobal变量实例(甚至可以是不同的)。