Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как использовать LoadLibrary в FMX-проектах на не-Windows платформах для динамической загрузки библиотек без подключения WinAPI?

Delphi , Файловая система , DLL и PlugIns

Динамическая загрузка библиотек в 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 могут возникнуть дополнительные сложности:

  1. Проблемы с путями: Начиная с Android 11, доступ к внешним хранилищам ограничен.
  2. Права доступа: Необходимо убедиться, что приложение имеет соответствующие разрешения.

Правильный подход для 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.

Рекомендации по динамической загрузке библиотек

  1. Проверка наличия функций: Всегда проверяйте результат GetProcAddress:

ExportFunc := GetProcAddress(LibHandle, 'Launch');

if not Assigned(ExportFunc) then raise Exception.Create('Функция не найдена в библиотеке');

  1. Обработка ошибок: Используйте try..except для обработки возможных ошибок.

  2. Размещение библиотек: На Android размещайте библиотеки во внутреннем хранилище приложения:

 LibPath := TPath.Combine(TPath.GetDocumentsPath, 'libs', 'mylibrary.so');

  1. Кросс-платформенные имена: Учитывайте различия в именах библиотек:
  2. Windows: mylibrary.dll
  3. Linux/Android: libmylibrary.so
  4. 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




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: DLL и PlugIns ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-05-01 06:42:17/0.0055160522460938/1