静态成员变量在可执行文件和dll之间不全局 [英] Static member variable not global between executable and dll

查看:96
本文介绍了静态成员变量在可执行文件和dll之间不全局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

就链接DLL的工作方式而言,我的知识有点模糊,但是我观察到可执行文件中的静态成员变量发生了变化,而该变化不会更改DLL中的相同静态成员变量.这是我遇到的情况:

My knowledge is a bit fuzzy in terms of how linking a DLL works but I'm observing a change to a static member variable in an executable that doesn't change the same static member variable in a DLL. Here's the scenario I have:

main.cpp静态链接到mylib.lib.在mylib.lib中,我具有以下类:

main.cpp is statically linked to mylib.lib. Within mylib.lib, I have the following class:

// foo.h
class Foo
{
public:
    static int m_global;
    Foo();
    ~Foo();
};

// foo.cpp
#include "foo.h"

int Foo::m_global = 5;

我还有一个链接到mylib.lib的DLL,其内容如下:

I also have a DLL that links to mylib.lib with the following:

//testdll.h
#define MATHLIBRARY_API __declspec(dllimport)

void MATHLIBRARY_API printFoo();

// testdll.cpp
#include "testdll.h"
#include <iostream>

void printFoo() {
    std::cout << Foo::m_global << std::endl;
}

最后,在我的可执行文件的main.cpp中

Finally, in main.cpp of my executable

// main.cpp
#include <iostream>
#include "testdll.h"
#include "foo.h"

int main() {
    std::cout << Foo::m_global << std::endl;
    Foo::m_global = 7;

    std::cout << Foo::m_global << std::endl;
    printMutiply();

    return 0;
}

我的预期输出是5、7、7.但是,我看到的是5、7、5,这告诉我DLL没有看到静态成员变量的更改.为什么会这样呢?以及如何使DLL看到可执行文件中的静态成员变量中的更改?

My expected output is 5, 7, 7. However, I'm seeing 5, 7, 5 which is telling me that the static member variable change isn't being seen by the DLL. Why is this so? And how can I make the DLL see changes in the static member variable made in the executable??

推荐答案

信不信由你,但您的应用程序违反了一个定义规则",因此触发了未定义行为".您的program(在C ++标准中被称为)最终具有Foo::m_global的双重定义-一个在可加载库中,另一个在main内部.作为这种未定义行为的可观察到的效果,Microsoft动态加载程序创建了两个符号,一个符号来自可加载对象,另一个符号来自main.

Believe it or not, but your application violates One Definition Rule, and as such, triggers Undefined Behavior. Your program (as it is called in C++ standard) ends up having double definition of Foo::m_global - one in the loadable library, and another one inside main. As an observable effect of this undefined behavior, Microsoft dynamic loader creates two symbols, one from loadable object, another from main.

在Linux中,ld(Linux加载程序)实际上会将那些符号合并为一个(这反过来会触发非平凡对象的双重破坏).

In Linux word, ld (linux loader) would actually conflate those symbols into one (which would, in turn, trigger double destruction for non-trivial objects).

底线-在可加载库和可执行文件之间不共享全局符号的定义.这对于函数和变量都适用,但是共享函数通常没有明显的副作用,尽管从技术上讲也是未定义的行为.

Bottom line - do not share definitions of global symbols between loadable libraries and executable. This goes for both functions and variables, but sharing functions usually does not have a visible side-effect, although technically is undefined behavior as well.

这篇关于静态成员变量在可执行文件和dll之间不全局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆