【发布时间】:2015-11-03 15:46:58
【问题描述】:
首先,有一些类似的问题,但没有一个真正解决确切的问题:
所以,这是我的问题:我正在开发一个 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 实例存在于加载进程使用的同一内存空间中。也许……
【问题讨论】:
-
当然,instanceCount 应该是
atomic。 -
对,实际上我有一个关键部分,但我想要一个简单的例子。
-
不,实际上你需要
atomic,而不是CRITICAL_SECTION,为此。CRTICAL_SECTIONs 只能在一个进程内工作,不能跨进程。 -
见 Serge 的评论。这是“重新加载”同一个 DLL 的同一个过程,这并不是真正的事情,所以当 DLL 被“重新加载”时,我实际上只是在访问相同的变量。所以真的我的问题措辞不佳,因为进程不可能重新加载 DLL。但是,如果在同一个 DLL 上进行多个 ::LoadLibrary 调用,那么在该 DLL 中访问的变量将在类实例之间共享(我认为。)
-
你仍然应该使用
atomic。
标签: c++ windows unix dll static