在同一 DLL 的实例之间共享静态变量和全局变量

Joh*_*eph 3 c++ unix windows dll static

首先,有一些类似的问题,但没有一个真正解决确切的问题:

https://social.msdn.microsoft.com/forums/vstudio/en-US/b7701ee5-c9fa-4693-8ae1-d59736360514/question-about-static-variables-in-dll

http://cboard.cprogramming.com/cplusplus-programming/101543-global-static-variable-class-delivered-dll.html

所以,这是我的问题:我正在开发一个 VST 插件,并且我有一个在 DLL 中定义和实现的类。加载同一个 DLL 的多个实例,我想做的是维护一个“实例计数”来监视类的构造次数(仅在根据 VST 标准加载 DLL 时发生一次)。

一种简单的方法是创建一个类静态变量,将其初始化为 0 并在构造函数中递增/在析构函数中递减。我确信我知道我的类何时被构造和析构,但我不确定该类静态变量是否会在我的 DLL 实例之间共享。

澄清一下,我多次加载同一个 DLL;DLL 中是一个类(仅在 DLL 代码中使用,不暴露给应用程序。)有一些关于 DLL 中定义的数据的行为在 Windows 和 Unix 之间是否有所不同的讨论,所以我想知道如果在 DLL 中执行此类操作对于跨平台使用是安全的。

示例类,在 DLL 中定义,不以任何方式暴露给加载 DLL(或其他方式)的应用程序。

头文件

// Foo.h
# pragma once
class Foo {
    static int s_InstanceCount;
public:
    Foo();
    ~Foo();
};
Run Code Online (Sandbox Code Playgroud)

现在是源文件

// Foo.cpp
#include "Foo.h"
int Foo::s_InstanceCount = 0;

Foo::Foo() {
    s_InstanceCount++;
}

Foo::~Foo() {
    s_InstanceCount--;
    if (s_InstanceCount == 0) {
        // Do something
    }
}
Run Code Online (Sandbox Code Playgroud)

Foo 的构造函数仅在应用程序加载 DLL 时调用(即 Windows 上的 ::LoadLibrary),而析构函数仅在释放 DLL 时调用(即 Windows 上的 ::FreeLibrary)。考虑一下这是有保证的。s_InstanceCount 会在构造函数的调用之间共享吗?

编辑:正如 Serge 下面指出的,一个进程不能真正加载 DLL 两次。因此,当我的 DLL 被一个进程加载两次时,构建的 Foo 实例存在于加载进程使用的同一内存空间中。或许...

Chr*_*phe 5

DLL 只是在调用它的进程的地址空间中运行的共享代码。每个进程都有自己的 DLL 中定义的全局/静态变量的副本。

本文向您解释这一点。但它也提供了一个很好的解决方法,可以使用文件映射在多个进程之间共享数据。这应该可以帮助您解决您的问题。

编辑:显然还有另一种解决方案,创建共享数据段(即告诉链接器共享一些数据,就像代码一样)。这里有microsoft doc和codeproject 上的概念验证。我从未使用过它,因此它是否也适用于静态类成员还有待测试。