Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows


Функция DllMain и библиотека С/С++


Рассматривая функцию DllMain в предыдущих разделах, я подразумевал, чтодля сборки DLL Вы используете компилятор Microsoft Visual C++. Весьма вероятно, что при написании DLL Вам понадобится поддержка со стороны стартового кода из библиотеки С/С++. Например, в DLL есть глобальная переменная — экземпляр какого-то С++класса. Прежде чем DLL сможет безопасно ее использовать, для переменной нужно вьзвать ее конструктор, а это работа стартового кода

При сборке DLL компоновщик встраивает в конечный файл адрес DLL-функции входа/выхода. Вы задаете этот адрес компоновщику ключом /ENTRY. Если у Вас компоновщик Microsoft и Вы указали ключ /DLL, то по умолчанию он считает, что функция входа/выхода называется _DllMainCRTStartup. Эта функция содержится в библиотеке С/С++ и при компоновке статически подключается к Вашей DLL - даже если Вы используете DLL-версию библиотеки С/С++.

Когда DLL проецируется на адресное пространство процесса, система па самом деле вызывает именно _DllMainCRTStartup, а не Вашу функцию DllMain. Получив уведомление DLL_PROCESS_ATTACH, функция _DllMainCRTStartup инициализирует библиотеку С/С++ и конструирует все глобальные и статические С++-объекты Закончив, _DllMainCRTSlartup вызывает Вашу DllMain

Как только DLL получает уведомление DLL_PROCESS_DETACH, система вновь вызывает _DllMainCRTStartup, которая теперь обращаемся к Вашей функции DllMain, и, когда та вернет управление, _DllMainCRTStartup вызовет деструкторы для всех глобальных и статических С++-объекгов. Получив уведомление DLL_THREAD_ATTACH, функция _DllMainCRTStartup не делает ничего особенного. Но в случае уведомления DLL_THREAD_DETACH, она освобождает в потоке блок памяти tiddata, если он к тому времени еще не удален. Обычно в корректно написанной функции потока этот блок отсутствует, потому что она возвращает управление в _threadstartex из библиотеки С/С++ (см. главу 6). Функция _threadstartex сама вызывает _endtbreadex, которая освобождает блок tiddata до того, как поток обращается к ExitThread




Начало  Назад  Вперед



Книжный магазин