Определите, является ли DLL_PROCESS_DETACH последней - PullRequest
0 голосов
/ 18 октября 2019

Я работаю над dll с компонентами пользовательского интерфейса, и в соответствии с документацией MSDN нам нужно явно отменить регистрацию оконных классов, зарегистрированных в dll. (в отличие от регистрации внутри процесса non dll, где система автоматически отменяет их регистрацию)

Теперь проблема в том, что в сообщении DLL_PROCESS_DETACH в функции DllMain мы можем сказать, когда процесс выгружает dll или завершает его,но как определить, будет ли dll полностью выгружена из памяти?

, потому что отмена регистрации классов окна при каждом отсоединении процесса - неподходящее время, так как другие окна все еще могут использовать зарегистрированный класс.

Я хочу отменить регистрацию всех классов, как только никакой другой процесс не "использует" dll. это похоже на правильное время для этого.

Вот как я сейчас отменяю регистрацию всех классов:

BOOL APIENTRY DllMain(
    HMODULE hModule,
    DWORD  ul_reason_for_call,
    [[maybe_unused]] LPVOID lpReserved) noexcept
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;

    case DLL_PROCESS_DETACH:
        /*
        * Note As it turns out, HMODULEs and HINSTANCEs are exactly the same thing. 
        * If the documentation for a function indicates that an HMODULE is required, you can pass an HINSTANCE and vice versa.
        * There are two data types because in 16-bit Windows HMODULEs and HINSTANCEs identified different things
        */

        // static method call to Unregister all window classes
        wsl::ui::ClassAtoms::UnregisterClassAtoms(hModule);
        break;
    }

    return TRUE;
}

Вот реализация, если вам любопытно, но она не актуальна.

namespace wsl::ui
{
    class ClassAtoms
    {
    public:
        static void AddClassAtom(const ATOM& atom)
        {
            mAtoms.push_back(atom);
        }

        static void UnregisterClassAtom(const ATOM& atom, const HINSTANCE& hInstance)
        {
            // If the class could not be found or if a window still exists
            // that was created with the class, the return value is zero.
            if (!UnregisterClass(MAKEINTATOM(atom), hInstance))
            {
                ShowError(ERR_BOILER);
            }
        }

        static void UnregisterClassAtoms(const HINSTANCE& hInstance)
        {
            for (auto& ref : mAtoms)
            {
                UnregisterClassAtom(ref, hInstance);
            }

            mAtoms.clear();
        }

    private:
        inline static std::vector<ATOM> mAtoms = {};

        // deleted
        ClassAtoms() = delete;
        ~ClassAtoms() = delete;
        ClassAtoms(const ClassAtoms&) = delete;
        ClassAtoms(ClassAtoms&&) = delete;
        ClassAtoms& operator=(const ClassAtoms&) = delete;
        ClassAtoms& operator=(ClassAtoms&&) = delete;
    };
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...