Подтвердить что ты не робот

Что делает AFX_MANAGE_STATE (AfxGetStaticModuleState()) точно

Я использовал множество модальных диалогов, и они отлично работали без использования AFX_MANAGE_STATE, но в последнее время я работал над другим проектом, в котором dll ресурсов отличаются от запуска dll. Я просмотрел веб-страницы и выяснил вышеприведенную строку, и когда я вставил ее перед запуском диалога, это сработало. Я предполагаю, что, может быть, так как у нас разные библиотеки DLL, нам нужно загрузить состояние главной dll, чтобы запустить диалог, но я не уверен. Мне не удалось найти хорошее объяснение в любом месте в Интернете. Может ли кто-нибудь объяснить простым языком, что делает AFX_MANAGE_STATE и почему мне вдруг пришлось его использовать.

Спасибо.

4b9b3361

Ответ 1

Каждый файл .exe и .dll имеет внутренний дескриптор ресурса, указывающий на ваши диалоги и другие ресурсы. Если вы вызываете функцию в своей DLL, текущий дескриптор ресурса указывает на ресурсы в .exe, что неверно и нужно изменить на ресурсы библиотеки DLL.

Это то, что делает AFX_MANAGE_STATE.

Ответ 2

AFX_MANAGE_STATE - это макрос, который вызывает функцию ресурса, чтобы ресурс просматривался только в этой DLL, а не в EXE/DLL, из которого вызывается определенная функция. Этот макрос также вызывает класс AFX_MAINTAIN_STATE, который должен быть помещен в стек. Этот класс, при выходе из функции, reset ищет ресурс, так что EXE/DLL, вызывающая эту экспортированную функцию, получает ресурс для поиска.

В терминах С++:

// Some exported function that launches GUI or uses other resources
int GetSomething()
{
   AFX_MANAGE_STATE();
  ...
}

Будет что-то вроде (не совсем):

int GetSomething()
{
       SetResourceSearchingToThisDLL();

       AFX_MAINTAIN_STATE state_RAII; 

       //Use resource

       // Compiler will put destroctor call for state_RAII object here
       // which will mean AFX_MAINTAIN_STATE::~AFX_MAINTAIN_STATE()
       // And that would call something like:
       ResetResourceSearching();
}

Использование этого макроса в одном стеке вызовов DLL не повредит никому, так как Resource-Searching имеет некоторый счетчик использования, который вернется к вызывающему (ресурс DLL/EXE) только в том случае, если он достигнет 0.

Важно отметить, что не каждая библиотека MFC должна использовать этот макрос. Только если DLL загружается клиентом, отличным от MFC, может быть клиент C, консольное приложение на С++, клиент .NET и т.д. (Да, также может быть клиент приложения MFC Windows).

Если ваши EXE и DLL сделаны в MFC, используя ту же версию MFC/Compiler/linker и имеет один объект CWinApp, вам не нужно использовать этот макрос.