[英]Sharing static and global variables across instances of the same DLL
首先,有一些类似的问题,但没有一个真正解决确切的问题:
所以,这是我的问题:我正在开发一个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 doc和codeproject上的概念证明 。 我从来没有使用它,所以它仍然需要测试它是否适用于静态类成员。
不,您的示例中的s_InstanceCount
将对DLL的每个实例都是私有的。 此外,如果不调整DLL的文件名,通常无法在同一进程中多次加载它,如下所述: 多次加载相同的dll 。 如果DLL实例在您的情况下处于不同的进程中,那么您需要进程间通信,例如通过共享内存 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.