Операционная среда BlackBox базируется на механизме динамической загрузки модулей.
Это позволяет создавать компонентные программные системы
с очень гибкой архитектурой.
Модуль в BlackBox, как и в любой Оберон-системе - это одновременно синтаксическая конструкция,
единица исходного кода, архитектуры, единица инкапсуляции,
компиляции, распространения, развертывания и загрузки в память.
Откомпилированные модули BlackBox хранятся в виде двоичного машинного кода.
Они хранятся в файлах с расширением .ocf (Oberon Code File) в каталогах Code соответствующих
подсистем.
По мере необходимости двочиные модули загружаются в память,
динамически связываются («компонуются», «линкуются»), инициализируются и исполняются.
Перед загрузкой модуля выполняется загрузка и инициализация всех модулей, которые он импортирует
(циклический импорт модулей запрещен, структура системы всегда представляет собой направленный
ацикличный граф - даг).
Если вам трудно представить себе, «как все это работает», то можно провести аналогию между
.ocf-файлами и динамическими библиотеками операционной системы. Однако двоичные модули
содержат в себе кроме исполняемого кода и точек входа в процедуры символьную информацию
о сигнатурах процедур, дескприпторы всех типов модуля, и другую так называемую метаинформацию,
которая делает возможным метапрограммирование. Поддержка метаинформации появилась
в Оберонах в 1989 г. - впервые среди компилируемых языков. Несколько лет спустя
более слабый её аналог RTTI (Run-Time Type Information) стал вводиться и в другие
популярные платформы, например, Delphi.
В случае, если модуль не используется никакими другими компонентами системы, он может быть
выгружен из памяти. Далее можно загрузить его новую версию (что и происходит многократно в процессе
разработки в среде). Возможность динамической выгрузки модулей выгодно отличает Оберон-системы от платформы
.NET, в которой штатного механизмы для выгрузки сборки из памяти приложения нет (видимо, разработчики
недооценили значение этого механизма).
Примечание: на самом деле даже для выгруженного модуля в памяти сохраняются дескрипторы его типов,
что позволяет динамическим объектам существовать в памяти даже после выгрузки модуля.
Важной особенностью динамической модульности в Оберонах является строгий контроль безопасности.
Каждая сущность, экспортируемая модулем, помечается особой меткой - «отпечатком пальцев» (fingerprint).
При загрузке модуля в память проверяется совместимость его интерфейса со всеми клиентскими модулями.
Если модули-клиенты не совместимы с новой версией модуля, то он не будет загружен в память до тех пор,
пока все клиенты не будут адаптированы к его новой версии (как минимум, перекомпилированы).
Такой механизм обладает большими достоинствами - с одной стороны, исключена загрузка в память несовместимых
между собой модулей, с другой стороны, в случае изменений только части интерфейса модуля (например,
добавления в него новой сущности) все клиенты, которые не использовали измененную часть, останутся совместимыми
с новой версией. Это выгодно отличает обероновский механизм контроля совместимости от принятого в .NET,
который базируется на контроле версий. В .NET при самом мелком изменении интерфейса разработчик обязан
изменить версию сборки, что требует перекомпиляции абсолютно всех клиентов.
В текущей версии модули BlackBox являются переносимыми, но только в рамках одной аппаратной платформы
(если в них не используется прямых вызовов к библиотекам ОС). Это обусловлено, с одной стороны,
платформенно-независимым форматом двоичного модуля и механизма загрузки, с другой стороны - тем, что
они содержат непосредственный машинный код для конкретной аппаратной платформы.
BlackBox произошел от Oberon System V4 - и даже работая поверх другой операционной системы, представляет
собой достаточно автономную операционную среду, во многих аспектах напоминая «мини-ОС».
Кроме того, будучи интегрированной средой разработки и выполнения, по удоству и гибкости BlackBox
действительно уподобляется интерпретаторам, например, Smalltalk или LISP-средам.
Да, модули BlackBox могут быть статически скомпонованы в традиционное монолитное приложение, хотя на
практике это используется редко, ввиду малого удобства таких монолитных приложений.
См. Как создать программу *.exe.
Автор*: Ермаков. И.Е. Правки: Ильин А.С., Романченко Я.
|