Работа с динамическими библиотеками в Windows: когда и зачем использовать FreeLibrary после LoadLibrary?
При работе с динамическими библиотеками в операционных системах семейства Windows часто возникает вопрос о необходимости использования функции FreeLibrary после вызова LoadLibrary. В данной статье мы рассмотрим, когда и зачем это может быть необходимо, а также приведем примеры кода на Object Pascal (Delphi).
Загрузка и освобождение динамических библиотек
Функция LoadLibrary используется для загрузки динамической библиотеки (DLL) в адресное пространство процесса. Она возвращает дескриптор модуля (HMODULE), который затем используется для доступа к функциям и переменным, содержащимся в библиотеке.
Функция FreeLibrary предназначена для освобождения загруженной библиотеки. Она уменьшает счетчик ссылок на библиотеку, и если счетчик достигает нуля, библиотека освобождается из памяти.
Счетчик ссылок
Система Windows поддерживает механизм счетчика ссылок для каждой загруженной библиотеки. Когда процесс загружает библиотеку с помощью LoadLibrary, счетчик увеличивается. Если библиотека больше не нужна, и нет других ссылок на нее, можно вызвать FreeLibrary, чтобы уменьшить счетчик. Когда счетчик достигает нуля, библиотека освобождается.
Однако, если процесс завершает работу, все загруженные библиотеки будут автоматически освобождены, независимо от текущего значения счетчика ссылок. Это означает, что вызов FreeLibrary не является обязательным для освобождения библиотеки, но может быть хорошей практикой для управления ресурсами.
Пример кода
Рассмотрим пример функции, которая загружает адрес процедуры из DLL:
function GetProcedureAddress(var P: FARPROC; const ModuleName, ProcName: AnsiString): Boolean;
var
ModuleHandle: HMODULE;
begin
Result := False;
ModuleHandle := GetModuleHandle(PAnsiChar(ModuleName));
if ModuleHandle = 0 then
ModuleHandle := LoadLibrary(PAnsiChar(ModuleName)); // Нужно ли вызывать FreeLibrary?
if ModuleHandle <> 0 then
begin
P := Pointer(GetProcAddress(ModuleHandle, PAnsiChar(ProcName)));
if Assigned(P) then
Result := True;
end;
end;
И функция, использующая GetProcedureAddress для вызова функции из shlwapi.dll:
function PathMakeSystemFolder(Path: AnsiString): Boolean;
var
_PathMakeSystemFolderA: function(pszPath: PAnsiChar): BOOL; stdcall;
begin
Result := False;
if GetProcedureAddress(@_PathMakeSystemFolderA, 'shlwapi.dll', 'PathMakeSystemFolderA') then
Result := _PathMakeSystemFolderA(PChar(Path));
end;
Нужно ли вызывать FreeLibrary?
Вопрос о необходимости вызова FreeLibrary после LoadLibrary является предметом дискуссий. С одной стороны, автоматическое освобождение библиотеки при завершении процесса делает вызов FreeLibrary необязательным. С другой стороны, освобождение ресурсов при их неиспользовании является хорошей практикой программирования.
Согласно документации Microsoft, GetModuleHandle не увеличивает счетчик ссылок, в отличие от LoadLibrary. Следовательно, FreeLibrary не должен вызываться для дескрипторов, полученных через GetModuleHandle.
Заключение
Использование FreeLibrary после LoadLibrary может быть опциональным, но рекомендуется для улучшения управления ресурсами вашего приложения. Важно понимать, что автоматическое освобождение библиотек при завершении процесса делает вызов FreeLibrary необязательным для освобождения самого процесса, однако это может быть важно для оптимизации работы приложения и освобождения ресурсов до окончания его жизни.
При написании кода, особенно в многозадачных или многопоточных приложениях, важно учитывать потенциальные проблемы с блокировкой и порядком освобождения библиотек, чтобы избежать утечек памяти или других ошибок, связанных с управлением ресурсами.
Описание контекста: Вопрос о необходимости использования функции `FreeLibrary` в Windows после использования `LoadLibrary` для загрузки и освобождения динамических библиотек, с учетом механизма счетчика ссылок и автоматизации процессов операционной систе
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.