Во-первых, есть некоторые подобные вопросы к этому, но никто на самом деле не решить точный вопрос:Совместное использование статических и глобальных переменных для экземпляров одного и того же DLL
Итак, вот мой вопрос: я работаю над плагином VST, и у меня есть класс, который определен и реализован в DLL. Множество экземпляров этой же DLL загружается, и я бы хотел, чтобы это «счетчик экземпляров», который контролирует, сколько раз класс создается (что происходит только один раз, когда DLL загружается по стандарту VST).
Одним из простых способов сделать это было бы создание статической переменной класса, которую я инициализирую до 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 загружается приложением (то есть :: LoadLibrary в Windows), а деструктор вызывается только тогда, когда DLL освобождается (т.е. :: FreeLibrary в Windows). Считайте это гарантированным. Будет ли s_InstanceCount использоваться совместно с вызовами конструктора?
EDIT: Как указывает Серый, процесс не может загрузить DLL дважды. Итак, когда моя DLL загружается дважды одним процессом, создаваемые Foo экземпляры существуют в том же пространстве памяти, которое используется процессом загрузки. Возможно ...
Конечно, instanceCount должен быть «атомным». –
Правильно, на практике у меня критический раздел, но мне нужен простой пример. –
Нет, на практике вам нужно «атомное», а не «CRITICAL_SECTION», для этого. 'CRTICAL_SECTION' работает только в процессе, а не в перекрестном процессе. –