c++ - 使用 mingw 在每个新库或可执行文件中重新初始化本地静态对象

标签 c++ gcc static mingw dynamic-linking

我建立了一个类工厂,它使用 map 的本地静态对象来保存它可以创建的所有类的名称:

typedef std::map<std::string, ClassFactory*> typeMap;

static typeMap& getMap() {
    static typeMap map;
    return map;
}

类必须使用此代码注册到 map :

DerivedRegistering(std::string const& s) {
    std::cout << "Inserting " << s << std::endl;
    std::cout << "Map size " << getMap().size() << std::endl;
    getMap().insert(std::make_pair(s, this));
}

如果我想创建一个新实例,我调用类的静态 createInstance 函数:

static Object* createInstance(std::string const& s) {
    std::cout << "Current map size " << getMap().size() << std::endl;
    typeMap::iterator it = getMap().find(s);
    if(it == getMap().end()) // not registered
        return 0;
    return it->second->create();
}

假设我已经在库 A 的头文件中创建了此类工厂,并且我正在将库 A 动态链接到一个项目,该项目链接另一个动态库 B 并最终创建一个可执行文件。

现在在 linux 下使用 gcc 我没有遇到任何问题,但是当使用 mingw 在 Windows 上做同样的事情时我遇到了问题。

gcc 的输出:

Registering classes of library B:
Inserting BA
Map size 0
Inserting BB
Map size 1
Inserting BC
Map size 2
Inserting BD
Map size 3
Inserting BE
Map size 4

Registering classes of library A:
Inserting AA
Map size 5
Inserting AB
Map size 6
Inserting AC
Map size 7
Inserting AD
Map size 8
Inserting AE
Map size 9
Inserting AF
Map size 10
Inserting AG
Map size 11

calling create instance in executable:
Current map size 12

但是在 mingw 中我得到这样的输出:

Registering classes of library B:
Inserting BA
Map size 0
Inserting BB
Map size 1
Inserting BC
Map size 2
Inserting BD
Map size 3
Inserting BE
Map size 4

Registering classes of library A:
Inserting AA
Map size 0
Inserting AB
Map size 1
Inserting AC
Map size 2
Inserting AD
Map size 3
Inserting AE
Map size 4
Inserting AF
Map size 5
Inserting AG
Map size 6

calling create instance in executable:
Current map size 0

所以对我来说,mingw 似乎为每个库和可执行文件创建了一个新的静态本地映射,而 gcc 为所有这些使用相同的内存。

正如您可能猜到的那样,GCC 行为是您所期望的行为。我可以为 mingw 强制执行此操作吗?

最佳答案

您的函数是静态的并且包含在多个地方。这意味着您会创建不同的主体和不同的对象。

在.h 中创建函数extern 并在.cpp 文件中添加一个单独的主体,然后您将拥有一个单例。

或者,您可以将其设为内联而不是静态,以获得相同的效果。

关于c++ - 使用 mingw 在每个新库或可执行文件中重新初始化本地静态对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17019083/

相关文章:

c++ - GCC 和 MS 编译器的模板实例化细节

dynamic - 调用COBOL程序的默认模式是什么?静态还是动态?

generics - TypeScript:继承类中方法的自引用返回类型

c++ - 我想在ROS中使用一些C代码,它使用C++语言

c++ - 使用指针实例化类

linux - 使用 cygwin (windows) 的 i686 的 GCC 交叉编译器 - 构建 GCC 失败

c - 如何在 Linux 上硬编码动态库路径

c - 从c中的另一个文件更新静态全局变量

c++ - 从二进制文件读取

c++ - 静态/动态运行时链接