繁体   English   中英

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

[英]Sharing static and global variables across instances of the same DLL

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

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();
};

现在是源文件

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

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

Foo::~Foo() {
    s_InstanceCount--;
    if (s_InstanceCount == 0) {
        // Do something
    }
}

Foo的构造函数仅在应用程序加载DLL时调用(即Windows上的:: LoadLibrary),并且仅在释放DLL时调用析构函数(即Windows上的:: FreeLibrary)。 考虑到保证。 是否会在对构造函数的调用之间共享s_InstanceCount?

编辑:正如Serge在下面指出的那样,进程无法真正加载DLL两次。 因此,当我的DLL被一个进程加载两次时,构造的Foo实例存在于加载过程使用的相同内存空间中。 也许...

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

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

编辑:显然有另一个解决方案,创建一个共享数据段(即告诉链接器共享一些数据,就像它对代码一样)。 这里有microsoft doccodeproject上的概念证明 我从来没有使用它,所以它仍然需要测试它是否适用于静态类成员。

不,您的示例中的s_InstanceCount将对DLL的每个实例都是私有的。 此外,如果不调整DLL的文件名,通常无法在同一进程中多次加载它,如下所述: 多次加载相同的dll 如果DLL实例在您的情况下处于不同的进程中,那么您需要进程间通信,例如通过共享内存

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM