外部指针在静态库中为空,当不是静态库时工作正常
Extern pointer is null in static library, worked fine when not a static library
我把我的Visual Studio项目(2015,c++)分成了三个部分:
- 静态库中的主应用程序
- 只有main函数的可执行文件
- 使用静态.lib文件的单元测试,以便可以导入所需的类并对其进行单元测试。
在我把它分成lib/exe/tests之前,主应用程序只是一个独立的可执行文件,它运行得非常好。
现在我不能只运行main函数的可执行文件,单元测试也不能因为某个指针总是空的。唯一的主要区别是,我在这个例子中使用了一个原始指针,但我在我的代码中使用了一个unique_ptr(目前,我切换到原始指针只是为了确保下面的例子是尽可能准确的,它没有神奇地编译/运行正确的原始指针)。
代码看起来与下面的代码非常相似(额外的代码被删除了):
// console.hpp
extern Console *console;
实现cpp文件(只包含需要的部分):
// console.cpp
Console *console = new Console();
现在在一些不相关的函数中,由于控制台指针是nullptr,这段代码失败了:
// some_other_file.cpp
#include "console.hpp"
// Inside some function...
console->doSomething(); // console is NULL
同样,我的代码在一个项目中工作得很好。无论如何,它编译得很好,没有链接错误,即使它被分成3个部分,但现在指针总是空的。
最后一个有趣的注意事项是,全局和外部的非指针变量都可以工作。这是否仅限于指针/unique_ptrs?
这是可以通过单例模式修复的吗?
线索在这条注释中:"似乎在主函数之前调用了其他代码,这些代码不让全局变量初始化。"
引用console
的代码可能是作为另一个全局变量初始化的一部分运行的,在这种情况下,发生在console
初始化之前。你必须非常小心地确保你没有依赖于全局初始化器的顺序。在拆分程序之前,你可能很幸运,现在你的运气已经用完了。
这里有一个常见的模式:
Console *GetConsole() {
static Console *console = new Console();
return console;
}
现在console不再是一个全局变量。所有想要访问控制台的东西都调用GetConsole
。
函数局部静态变量将在第一次调用函数时初始化,之后它只返回值。如果您有多个线程和较旧的编译器,则必须做更多的工作来防止可能的竞争条件。现代编译器应该以线程安全的方式进行初始化。
相关文章:
- GCC:--静态链接到pthread的整个存档配方在最近的GCC版本中停止工作
- C++ 已停止工作静态映射函数
- 静态 constexpr 函数在模板结构中工作,但不能在结构中工作.为什么?
- C 11螺纹 - 非静态成员功能的使用无效 - 工作GCC 5.1.0损坏的GCC 7.3.1
- 从 WebAPI 项目运行静态类时出现 StackOverflow 异常 - 从控制台应用程序运行时工作正常
- 初始化静态成员使编译工作.但是为什么
- 在dll中静态对象的破坏之前,要终止工作线程(但不是.exe)
- 嵌套静态循环由于无法捕获 constexpr 而无法工作
- 通过静态成员功能使ADL工作
- 如何设计一个配置实用程序来静态和动态链接工作
- 为什么单例在这里工作,尽管静态变量被重新初始化为 NULL
- 我的wlanregisternotification回调仅在回调为静态时工作
- 静态分配的可变大小数组如何在C++中工作
- 从静态方法访问非静态成员的工作示例
- 谷歌静态地图图像不在Tizen设备上工作,但在模拟器上
- 无法理解静态概念在这里的工作
- 无法使用VS2012链接到静态升压库,而动态链接工作正常
- C++ 具有静态成员工作的寄存器模式"sometimes"
- 元件与工作灯静态库冲突
- 我应该使用静态工作池还是动态工作池(线程)