пятница, 12 апреля 2013 г.

Кросс-платформенные библиотеки

Перевод раздела Cross-Platform Shared Libraries из справочной системы Delphi

Совместное использование библиотек в приложениях Mac OS X

При разработке кросс-платформенных библиотек в Delphi, необходимо изучить некоторые требования, налагаемые платформами. В особенности это касается функций в библиотеках для OS X, которые необходимо вызывать и загружать динамически. Необходимо помнить, что:

  • Имена динамически загружаемых функций должны начинаться с нижнего подчеркивания ('_').
  • Инструкции exports должны быть перемещены из файлов .dpr в файлы .pas.

Эти два правила разъясняются далее.


Динамически загружаемые функции для OS X требуют, чтобы их имена начинались с нижнего подчеркивания ('_')

Рассмотрим соглашение об именовании для целевой платформы OS X: оно требует наличия символа нижнего подчеркивания в начале названий функций, которые будут экспортированы в OS X.

Это правило необходимо соблюдать в приложениях для OS X, поскольку стандартная библиотечная функция dlsym(), схожая по своему назначению с GetProcAddress() в WinAPI, добавляет в начало имен функций, доступ к которым выполняется динамически, символ нижнего подчеркивания. Библиотека создается обычным образом и статически связывается при компиляции, но при динамическом вызове функций в программе, доступ к ним будет невозможен при отсутствии нижнего подчеркивания в названии функции.

Инструкции Exports недопустимы в файлах .dpr

При разработке библиотек для Mac OS X, переместите инструкции exports из файла.dpr, содержащего код библиотеки, в файлы .pas, в которых объявляются экспортируемые функции.

Пример программного кода

Например, приведенный ниже модуль предназначен для экспорта функции, имя которой изменяется в зависимости от целевой платформы:

  • Windows: TestProc()
  • OS X: _TestProc()
unit uTestLib;
 
 interface
 
 {$IFDEF MACOS}
 function _TestProc(var I: Integer): Integer; cdecl;
 {$ELSE}
 function TestProc(var I: Integer): Integer; cdecl;
 {$ENDIF}
 
 exports 
 {$IFDEF MACOS}
   _TestProc;
 {$ELSE}
   TestProc;
 {$ENDIF}
 
 implementation
 {$IFDEF MACOS}
 function _TestProc(var I: Integer): Integer; cdecl; export;
 {$ELSE}
 function TestProc(var I: Integer): Integer; cdecl; export;
 {$ENDIF}
 begin
   Result := I;
 end;
 end.

Обращение к функции в OS X одним из способов:

  • System.SysUtils.GetProcAddress()
  • Posix.Dlfcn.dlsym()

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

Замечание: Это требование касается динамически загружаемых функций и не относится к функциям, линкуемым статически с применением директивы external, добавляемой к объявлению функции. Имена статически линкуемых функций также могут начинаться с символа нижнего подчеркивания (обычно в OS X это так и есть), но это не является обязательным, как в случае с динамически загружаемыми функциями.

Также необходимо учитывать, что в библиотеках, разрабатываемых для OS X, раздел exports, расположенный в главном файле библиотеки.dpr не распознается. Раздел exports для экспортируемых функций должен быть включен в файл модуля, как это показано в приведенном выше примере.

Прочие условия

Компиляция библиотек с включением пакетов времени исполнения

И библиотеки (DLL) и приложения должны компилироваться с включением пакетов времени исполнения. В противном случае все они будут иметь свою копию глобальных объектов, таких как Platform и Application.

Вызов LoadLibrary

LoadLibrary должна вызываться после запуска приложения. Загрузка DLL при инициализации модулей не работает.

Комментариев нет:

Отправить комментарий