DLL создаются аналогично файлам .EXE: компилируются файлы
исходного кода, затем выполняется компоновка объектных файлов.
Однако, DLL не имеют функции main и компонуются по другому. Ниже
рассказывается, как следует писать DLL.
LibMain, DllEntryPoint и WEP
В качестве основной точки входа для DLL должны предусматриваться функция LibMain (для 16-разрядных программ) или DllEntryPoint (для 32-разрядных). В случае 32-разрядных программ Windows
вызывает DllEntryPoint при каждой загрузке или выгрузке DLL, при
каждом присоединении или отсоединении от DLL дополнительных процессов или при создании/уничтожении внутри процесса нити.
Инициализация DLL практически целиком зависит от функции
конкретной DLL и может включать в себя следующие основные задачи:
она описывается как MOVEABLE (только для 16-битовых приложений).
Код инициализации выполняется только для первого приложения,
использующего DLL. Код запуска DLL автоматически инициализирует
локальную динамически распределяемую область памяти, поэтому в
LibMain не нужно включать соответствующий код. Функции LibMain
передаются следующие параметры:
int FAR PASCAL LibMain (HINSTANCE hInstance, WORD wDataSeg;
WORD cbHeapSize, LPSTR lpSmdLine)
hInstance - это описатель экземпляра DLL.
wDataSeg - это значение регистра сегмента данных (DS).
cbHeapSize - размер локальной динамически распределяемой
области памяти, заданной для DLL в файле определения модуля.
lpCmdLine - это дальний указатель командной строки, задан ной при загрузке DLL. Он почти всегда нулевой, так как DLL
обычно загружается автоматически и без параметров.
LibMain обычно возвращает значение 0 (успешная инициализация) или 1 (неуспешная инициализация). В последнем случае Windows
выгружает DLL из памяти.
Точкой выхода для 16-битовой DLL является функция WEP (Windows Exit Procedure). Эта функция для DLL не обязательна, так как
библиотеки исполняющей системы Borland C++ предусматривают ее по
умолчанию, но для выполнения какой-либо очистки перед выгрузкой
DLL из памяти вы можете указать свою собственную функцию.
В Borland С++ WEP экспортировать не требуется. Borland С++
определяет свою собственную WEP, которая вызывает вашу WEP (если
она определена), а затем выполняет очистку системы. WEP имеет
следующий прототип:
int FAR PASCAL WEP (int nParameter)
где nParameter - это WEP_SYSTEMEXIT или WEP_FREE_DLL. WEP_SYSTEMEXIT указывает на завершение работы Windows, а WEP_FREE_DLL
только на выгрузку DLL. В случае успешного выполнения WEP возвращает 1. По этому значению Windows в настоящее время не выполняет
никаких действий.