Динамическая загрузка библиотек в FMX-проектах на не-Windows платформах
Проблема использования LoadLibrary в кроссплатформенных приложениях
При разработке кроссплатформенных приложений на Delphi с использованием FireMonkey (FMX) часто возникает необходимость динамической загрузки библиотек. Однако стандартная функция LoadLibrary из WinAPI работает только на Windows, что вызывает сложности при переносе кода на другие платформы, такие как Android, iOS, macOS и Linux.
Как отметил Remy Lebeau в обсуждении, LoadLibrary() - это функция Win32 API, поэтому она недоступна на других платформах. На Unix-подобных системах (включая OSX, iOS, Linux и Android) используется dlopen().
Решение: использование кросс-платформенных функций в Delphi
Вариант 1: LoadLibrary из System.SysUtils
Как указал Dave Nottage, в Delphi существует кросс-платформенная реализация LoadLibrary в модуле System.SysUtils, которая внутри использует соответствующие API для каждой платформы:
uses
System.SysUtils;
var
LibHandle: THandle;
begin
// Для Windows: LoadLibrary из WinAPI
// Для POSIX-систем: dlopen
LibHandle := LoadLibrary('mylibrary.so');
if LibHandle <> 0 then
begin
try
// Работа с библиотекой
finally
FreeLibrary(LibHandle);
end;
end;
end;
Вариант 2: SafeLoadLibrary
Более безопасной альтернативой является SafeLoadLibrary, которая также доступна в System.SysUtils:
uses
System.SysUtils;
var
LibHandle: THandle;
begin
LibHandle := SafeLoadLibrary('mylibrary.so');
if LibHandle <> 0 then
begin
try
// Работа с библиотекой
finally
FreeLibrary(LibHandle);
end;
end;
end;
Особенности работы на Android
Как показал пример Anna Blanca, при работе на Android могут возникнуть дополнительные сложности:
Проблемы с путями: Начиная с Android 11, доступ к внешним хранилищам ограничен.
Права доступа: Необходимо убедиться, что приложение имеет соответствующие разрешения.
Правильный подход для Android:
procedure TForm1.LoadAndroidLibrary;
var
LibPath: string;
LibHandle: THandle;
ExportFunc: function(X, Y: Integer): Integer;
begin
// Получаем путь к внутреннему хранилищу приложения
LibPath := TPath.Combine(TPath.GetDocumentsPath, 'libTestLibrary.so');
// Загружаем библиотеку
LibHandle := LoadLibrary(PChar(LibPath));
if LibHandle <> 0 then
try
ExportFunc := GetProcAddress(LibHandle, 'Launch');
if Assigned(ExportFunc) then
begin
Label1.Text := IntToStr(ExportFunc(3, 5));
end
else
Label1.Text := 'Функция не найдена';
finally
FreeLibrary(LibHandle);
end
else
Label1.Text := 'Библиотека не загружена';
end;
Альтернативное решение: создание кросс-платформенной обёртки
Для более гибкого управления можно создать собственную обёртку:
unit CrossPlatformLibraryLoader;
interface
function LoadCrossPlatformLibrary(const LibraryName: string): THandle;
function GetLibraryProcedure(LibHandle: THandle; const ProcName: string): Pointer;
procedure UnloadCrossPlatformLibrary(LibHandle: THandle);
implementation
uses
System.SysUtils;
function LoadCrossPlatformLibrary(const LibraryName: string): THandle;
begin
Result := SafeLoadLibrary(LibraryName);
end;
function GetLibraryProcedure(LibHandle: THandle; const ProcName: string): Pointer;
begin
Result := GetProcAddress(LibHandle, PChar(ProcName));
end;
procedure UnloadCrossPlatformLibrary(LibHandle: THandle);
begin
if LibHandle <> 0 then
FreeLibrary(LibHandle);
end;
end.
Рекомендации по динамической загрузке библиотек
Проверка наличия функций: Всегда проверяйте результат GetProcAddress:
Кросс-платформенные имена: Учитывайте различия в именах библиотек:
Windows: mylibrary.dll
Linux/Android: libmylibrary.so
macOS/iOS: libmylibrary.dylib
Заключение
Для динамической загрузки библиотек в FMX-проектах на не-Windows платформах следует использовать LoadLibrary или SafeLoadLibrary из System.SysUtils, которые обеспечивают кросс-платформенную функциональность. Особое внимание нужно уделить работе с путями и правами доступа на мобильных платформах, особенно на современных версиях Android.
Представленные решения позволяют реализовать динамическую загрузку библиотек, включая сценарии с загрузкой обновлённых версий из интернета, сохраняя при этом кросс-платформенность вашего приложения.
Контекст описывает способы динамической загрузки библиотек в кроссплатформенных FMX-проектах на Delphi, особенно на платформах, отличных от Windows, с учетом особенностей Android.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.