Модули

Модули предназначены для хранения стандартных готовых программ или наборов данных. В FPC поддерживаются:

  • Модули общего назначения.
  • Модули данных.
  • Модули динамических библиотек.

Модуль включается в программу при компиляции. Это увеличивает память программы. DLL подключается в ходе выполнения программы при обращении к процедуре или функции, описанной в ней, только на время использования. Память почти не занимается. Модуль может хранить и подпрограммы и данные, а DLL – только подпрограммы.

Модуль общего назначения

Структура модуля

Программа в FPC состоит из главной программы и (возможно) нескольких модулей. Применение модулей позволяет:

  • использовать метод бригадного программирования,
  • сократить объем основной программы,
  • при изменении подпрограммы перекомпилируется только она.

Модуль – хранилище стандартных готовых подпрограмм или данных. По своей структуре Модуль = Программа. Может храниться и компилироваться отдельно. Может использоваться другими программами или модулями путем вызова их подпрограмм по именам. Не используется автономно. Хранится в трех вариантах:

  • Модуль на языке FPC, <имя>.pas.
  • Компилированный ассемблерный модуль, <имя>.ppu.
  • Компилированный объектный модуль, <имя>.o.

Структура модуля:

unit <имя>;                           // Заголовок модуля

interface

<Интерфейсная часть>

implementation

<Исполняемая часть>

initialization                            // Не обязательно

<Инициирующая часть>

finalization                        // Не обязательно

<Завершающая часть>

end.

Имя модуля обязательно, оно используется для связи с вызывающей программой. Должно совпадать с именем файла с кодом модуля на FPC. Ссылка на подключаемые модули в вызывающей программе размещается в строке: uses <список модулей>. Интерфейсная часть interface содержит:

  • Ссылки на внешние модули, используемые в данном модуле.
  • Объявления глобальных объектов (типов, констант, переменных).
  • Заголовки (только) подпрограмм (функций и процедур).

Инициирующая часть initialization содержит инструкции, которые выполняются до передачи управления вызывающей программе. Например, инициируются переменные, открываются файлы и др. Завершающая часть finalization содержит инструкции, которые выполняются после завершения работы  вызывающей программы. Например, освобождаются выделенные программе ресурсы, закрываются файлы и др.

Модуль комплексной арифметики

unit Complex;                                    // Комплексная арифметика

{$mode objfpc}{$H+}

interface

uses

Classes, SysUtils;

type

TComplex = record                     // Тип комплексного числа

Re, Im: Real

end;

function AddC(x,y: TComplex):TComplex; // Комплексное сложение

function SubC(x,y: TComplex):TComplex;    // Комплексное вычитание

function MultC(x,y: TComplex):TComplex;   // Комплексное умножение

function DivC(x,y: TComplex):TComplex;     // Комплексное деление

implementation

function AddC(x,y: TComplex):TComplex;

begin

Result.Re:=x.Re + y.Re;

Result.Im:=x.Im + y.Im;

end;

function SubC(x,y: TComplex):TComplex;

begin

Result.Re:=x.Re – y.Re;

Result.Im:=x.Im – y.Im;

end;

function MultC(x,y: TComplex):TComplex;

begin

Result.Re:=x.Re*y.Re – x.Im*y.Im;

Result.Im:=x.Re*y.Im +  x.Im*y.Re;

end;

function DivC(x,y: TComplex):TComplex;

var  z: Real;

begin

z:=sqr(y.Re)+sqr(y.Im);

try                                         // Защита при делении на 0

Result.Re:=(x.Re*y.Re + x.Im*y.Im)/z;

Result.Im:=(x.Re*y.Im – x.Im*y.Re)/z;

except                                   // Если делитель 0, то

Result.Re:=1.1e309;

Result.Im:=1.1e309

end;

end;

end.

Динамически связываемая библиотека DLL

Введение

DLL = Dynamic Linked Library (Динамически связываемая библиотека). DLL – хранилище стандартных готовых подпрограмм. По своей структуре DLL = Программа. Хранится в двух вариантах:

  • DLL на языке FPC,  <имя>.pas. Это исходник.
  • Компилированная DLL, <имя>.dll. Содержит объектный код.

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

Одна и та же DLL может использоваться несколькими программами. Именно это является преимуществом использования DLL. В памяти имеется только один экземпляр библиотеки, к которому могут обращаться несколько программ. DLL содержит подпрограммы:

  • Экспортируемые, они помечены словом Export.
  • Внутренние.

Для обращения к подпрограмме используется внутренняя таблица, каждая строка которой содержит:

  • Индекс (номер). Вызов по номеру более быстрый, но его программисту нужно помнить.
  • Имя. Внутреннее для DLL.
  • Внешнее имя. Это синоним внутреннего имени, имя в вызывающей программе.
  • Адрес начала.
  • Признак Resident. Если он установлен, то загруженная DLL остается резидентной, даже если счетчик С пуст.

Для DLL запрещено экспортировать данные, так как она может использоваться одновременно несколькими программами или модулями, при обращении которых  к данным возможна конкуренция. DLL может создаваться и использоваться в программах на разных языках программирования. Доступ в ней к объектному коду. Поэтому нет зависимости от языка программирования DLL.

Структура DLL

library <имя>;                                        // Заголовок

function MyFunc(<параметры>:<тип>;Export;         // Функция экспорта

begin

<Тело функции>

end;

procedure MyProc;Export;                           // Процедура экспорта

begin

<Тело процедуры>

end;

exports                                                   // Списки экспорта

MyFunc,MyProc;

begin

<Инициирующая часть>                     // Часто пустая

end.

DLL содержит таблицу, в которой в строках с индексами, начиная от 0, находятся параметры подпрограммы (имя, внешнее имя, адрес начала, флаг Resident). Индекс можно задать:

  • Неявно (не указывая его). Подпрограммы нумеруются, начиная с 0, по мере их появления в списках Exports.
  • Явно, с использованием слова Index. Это рекомендуется, чтобы избежать путаницы.

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

Для каждой подпрограммы в списке обязательно указывается ее имя. После имени можно указывать дополнительные данные, имеющиеся во внутренней таблице DLL: слово Index, за которым следует номер, слово Name, за которым следует внешнее имя, признак Resident. Дополнительные данные могут следовать в любом порядке. Ключевые слова отделяются пробелами. Примеры оформления фразы exports:

exports

MyFunc index 1,

MyProc index 2;              // Явно добавлены номера после слова Index

exports

MyFunc name ‘NewFunc’;     // После слова Name задано иное внешнее имя

exports

MyFunc Resident;            // Установлен признак Resident

Вызывающая программа может вызвать подпрограмму:

  • По имени. Это медленно. Имен много и они длинные. Время затрачивается на поиск имени в таблице имен DLL.
  • При вызове по имени можно ускорить обращение, добавив слово Resident.
  • По индексу, это быстрее. Позиция в таблице выбирается сразу.

DLL комплексной арифметики

Подпрограммы такие же, как в ранее рассмотренном модуле комплексной арифметики. Их внешние имена такие же, а внутренние имена другие.

library DLL_Complex;                            // Заголовок DLL

type                                                  // Глобальный тип. Не экспортируется

TComplex= record                           // Запись

Re,Im:real;                             // Два поля – вещественные числа

end;

function CAdd(x,y:TComplex):TComplex;export;        // Функция сложения

begin

Result.Re:=x.Re+y.Re;

Result.Im:=x.Im+y.Im;

end;

function SubC(x,y:TComplex):TComplex;export;         // Функция вычитания

begin

Result.Re:=x.Re–y.Re;

Result.Im:=x.Im–y.Im;

end;

function CMult(x,y:TComplex):TComplex;export;        // Функция умножения

begin

Result.Re:=x.Re*y.Re–x.Im*y.Im;

Result.Im:=x.Re*y.Im+ x.Im*y.Re;

end;

function CDiv(x,y: TComplex):TComplex;export;        // Функция деления

var  z:Real;                             // Вспомогательная локальная переменная

begin

z:=sqr(y.Re)+sqr(y.Im);                     // Расчет знаменателя

try                                   // Защита от краха при делении на ноль

Result.Re:=(x.Re*y.Re+x.Im*y.Im)/z;

Result.Im:=(x.Re*y.Im–x.Im*y.Re)/z;

except

Result.Re:=1.1e309;   // При делении на 0 ответ очень большой

Result.Im:=1.1.e309;

end;

end;

end;

exports

CAdd index 1 ‘AddC’ resident,

CSub index 2,

CMult index 3,

CDiv index 4;

begin

end.

TwitterSEO CommunityВаау!News2.ruChippKoricaSMI2Google BookmarksDiggI.uaЗакладки YandexLinkstoreMyscoopCommunizmRu-marksWebmarksRuspaceLinkomaticKli.kzWeb-zakladkaZakladok.netRedditdeliciousMa.gnoliaTechnoratiSlashdotYahoo My WebБобрДобр.ruMemori.rurucity.comМоёМесто.ruMister Wong

Copyright © 2009-2010 Программирование на паскале.