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

Пакеты

Перевод раздела Packages (Delphi) из справочной системы Delphi

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


Понятие пакетов

Пакет – это специальная скомпилированная библиотека, которая используется приложениями и/или IDE. Пакеты позволяют упорядочить приложение без изменения его программного кода. Часто это называют "дроблением приложения".

Пакеты времени выполнения (runtime packages) обеспечивают функциональность приложения при его запуске. Пакеты разработки (design time packages) применяются при установке компонентов в IDE и разработке специализированных редакторов свойств для пользовательских компонентов. Один и тот же пакет может содержать функции времени выполнения и разработки. Кроме того, пакет разработки в своем разделе requires может содержать ссылки на пакеты времени выполнения.

На платформе Win32, файлы пакетов имеют расширение .bpl (Borland package library – пакетная библиотека Borland).
Обычно пакеты загружаются статически при запуске приложения. Но для динамической загрузки можно использовать и подпрограммы LoadPackage из UnloadPackage (из модуле SysUtils).

Замечание: при подключении пакета в приложение каждый его модуль, ссылающийся на модули пакета, должен содержать имена этих модулей в разделе uses.

Файлы программного кода пакетов и объявление пакетов

Каждый пакет объявляется в отдельном файле. Чтобы избежать путаницы с прочими файлами Delphi, такой файл должен быть сохранен с расширением .dpk. Файл программного кода пакета не содержит объявлений типов, данных, процедур или функций. Он содержит:

  • Имя пакета
  • Список пакетов, требуемых для этого пакета (связанные с ним пакеты).
  • Список файлов модулей, которые включены в пакет или связаны с ним при компиляции. Пакет по существу является оберткой для модулей, обеспечивающих его функциональность.

Объявление пакета имеет вид:

package packageName;

  requiresClause;

  containsClause;

end.

Где packageName – это любой допустимый идентификатор. Разделы requiresClause и containsClause являются необязательными. Следующий пример демонстрирует объявление пакета DATAX:

package DATAX;
   requires
   rtl,
   contains Db, DBLocal, DBXpress, ... ;
 end.

В разделе requires перечислены внешние пакеты, использованные объявляемым пакетом. Этот раздел состоит из директивы requires, за которой следует список имен пакетов, разделяемых запятыми. Если пакет не ссылается на другие пакеты, раздел requires не нужен.

Раздел contains определяет файлы модулей, которые необходимо скомпилировать в пакете. Он состоим из директивы contains, за которой следует список имен модулей, разделяемых запятыми. За любым именем модуля может следовать зарезервированное слово in имя файла с указанием (или без указания) полного пути к нему, заключенное в одинарные кавычки. Путь к файлу может быть как абсолютным, так и относительным. Например:

contains MyUnit in 'C:\MyProject\MyUnit.pas';
Замечание: Доступ к локальным переменным потоков (объявленным в модулях пакета при помощи threadvar) из приложений и модулей, подключающих этот пакет, невозможен.

Файлы пакетов

Скомпилированный пакет состоит из нескольких файлов. Например, исходный файл проекта с именем DATAX - это DATAX.DPK. Из него при компиляции генерируется исполняемый файл и двоичный образ с именами DATAX.BPL и DATAX.DCP.

Имя DATAX используется при обращении к пакету в разделах requires других пакетов или при использовании пакета в приложении. Имена пакетов должны быть уникальными в рамках одного проекта.

Раздел requires

В разделе requires перечисляются внешние пакеты, которые подключаются в текущий пакет. Этот раздел функционирует также, как и раздел uses в файле модуля. Внешний пакет, указанный в разделе requires, автоматически линкуется при компиляции в любое приложение, которое подключает текущий пакет или модуль из внешнего пакета.

Если файлы модулей, содержащихся в одном пакете, имеют ссылки на модули в других пакетах, эти пакеты должны быть перечислены в разделе requires первого пакета. Если эти имена этих пакетов отсутствуют в разделе requires, компилятор загружает запрошенные модули из файлов .dcu.

Избегание циклических ссылок

В разделах requires запрещены циклические ссылки. Это обозначает, что

  • Пакет не может ссылаться сам на себя в разделе requires.
  • Цепочки ссылок должны заканчиваться без повторения пакетов. Если пакет A ссылается на пакет B, то пакет B не может ссылаться на A; если пакет A ссылается на B, а пакет B ссылается на C, то пакет C не может ссылаться на пакет A.

Двойные ссылки на пакеты

Компилятор игнорирует повторные ссылки в разделе requires. Тем не менее, для порядка и удобства чтения программы двойные ссылки лучше удалять.

Раздел contains

Раздел contains определяет файлы модулей, которые должны быть скомпилированы в пакет. Расширения имен файлов в разделе contains указывать не следует.

Избегание избыточных ссылок

Пакет не может быть указан в разделе contains другого пакета или в разделе uses программного модуля.

Все модули, включенные в раздел contains пакета (прямое включение) или разделы uses его модулей (косвенное включение) помещаются в пакет во время компиляции. Модули, содержащиеся в пакете, не могут быть включены в состав других пакетов, перечисленных в разделе requires этого пакета.

Запрещается включение (прямое или косвенное) одного и того же модуля в нескольких пакетах, используемых в одном приложении.

Компиляция пакетов

Обычно компиляция пакетов выполняется из IDE, при этом файлы .dpk генерируются Менеджером Проектов (Project Manager). Вы можете компилировать файлы .dpk и непосредственно из командной строки. Если в проекте содержится пакет, то при компиляции этого проекта, пакет будет автоматически перекомпилирован при необходимости.

Файлы, создаваемые автоматически

В следующей таблице перечислены файлы, создаваемые при успешной компиляции пакета.

Расширение файлаСодержимое
DCPДвоичный файл, содержащий заголовок пакета и сцепку всех файлов.dcu (Win32), включенных в пакет. Файлы .dcp или .dcp создаются для каждого пакета. Файл получает такое же имя, что и программный файл пакета с расширением .dpk.
BPLПакет времени исполнения. Этот файл представляет собой динамически загружаемую библиотеку со специфической функциональностью, добавленной компанией Embarcadero. Файл получает такое же имя, что и программный файл пакета с расширением .dpk.


Директивы компилятора, связанные с пакетами

В следующей таблице перечислены директивы компилятора, добавление которых в программный код будет влиять на компиляцию пакетов.

ДирективаНазначение
{$IMPLICITBUILD OFF}Предотвращает автоматическую перекомпиляцию пакета. Эту директиву следует использовать в файлах.dpk при компиляции пакетов, программный код которых не будет распространяться или обеспечивает низкоуровневую функциональность, которая изменяется редко.
{$G-} или {$IMPORTEDDATA OFF}Отключает создание ссылок импортируемых данных. Эта директива увеличивает эффективность работы с памятью, но накладывает ограничения на ссылки из модуля на переменные, объявленные в других пакетах.
{$WEAKPACKAGEUNIT ON}Слабая упаковка модулей.
{$DENYPACKAGEUNIT ON}Предотвращает помещение модуля в пакет.
{$DESIGNONLY ON}Компиляция пакета для установки в IDE. (Директива указывается в файле.dpk.)
{$RUNONLY ON}Скомпилированный пакет может быть использован только как пакет времени выполнения (Директива указывается в файле.dpk.).

Включение директивы {$DENYPACKAGEUNIT ON} в программный код запрещает упаковку модуля. Включение директивы {$G-} или {$IMPORTEDDATA OFF} может предотвратить использование пакета другими пакетами в одном приложении.

Прочие директивы компилятора могут быть включены в программный файл пакета при необходимости.

Компиляция пакетов из командной строки

В следующей таблице перечислены ключи компилятора, связанные с компиляцией пактетов.

КлючНазначение
-$G-Отключает создание ссылок импортируемых данных. Эта директива увеличивает эффективность работы с памятью, но накладывает ограничения на ссылки из пакета на переменные, объявленные в других пакетах.
LE pathОпределяет директорий, куда будет помещен скомпилированный пакет.
LN pathОпределяет директорий, куда будет помещены файлы dcp или dcp.
LUpackageName[;packageName2;...]Определяет дополнительные пакеты времени выполнения для подключения в приложение. Используется при компиляции проекта.
ZПредотвращает автоматическую перекомпиляцию пакета. Эту директиву следует использовать при компиляции пакетов, программный код которых не будет распространяться или обеспечивает низкоуровневую функциональность, которая изменяется редко.

Применение ключа -$G- может предотвратить использование пакета другими пакетами в одном приложении.

Прочие ключи могут быть использованы при компиляции пакета при необходимости.

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

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