TURBO PASCAL

Новости

Программы   

Turbo Pascal 

Игры

Документация   

Странности

FAQ

Ссылки

Форум

Гостевая книга

Рассылка

Благодарности

Об авторе

 

 

9.5.1. Создание DLL

Для создания DLL в ВР введено зарезервированное слово Library, которым должен начинаться текст библиотеки. За словом Library следует правильный идентификатор, но в отличие от объявления модуля он не обязан совпадать с именем файла: имя DLL определяется именем DLL-файла, а не идентификатором, следующим за Library.

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

Сразу за заголовком экспортируемой подпрограммы должно следовать зарезервированное слово Export, которое заставит компилятор выработать специальный код пролога/эпилога. DLL имеют сегменты кода и данных, но у них нет сегмента стека. Специальный пролог/эпилог позволяет DLL— подпрограмме использовать сегмент стека вызвавшей ее программы.

В разделе описаний DLL могут объявляться типы (в том числе и объекты), константы и переменные, но они остаются скрытыми от вызывающей программы и могут использоваться только внутри DLL. В разделе описаний помимо стандартных для обычной программы объявлений используется специальный раздел объявления экспортируемых подпрограмм. Этот раздел начинается зарезервированным словом Exports, за которым через запятую перечисляются имена экспортируемых подпрограмм, например:

Library MyLibrary;

Function MyFunc(...):...; Export;

begin

end;

Procedure MyProc; Export;

begin

end;

Exports

MyFunc, MyProc;

begin end.

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

Помимо имени подпрограммы в заголовок DLL помещается также ее порядковый номер, точнее присвоенный ей целочисленный индекс. Это позволяет вызывающей программе ссылаться не на имя, а на индекс подпрограммы и тем самым уменьшить затраты времени на установление с ней связи. Индекс присваивается подпрограмме по порядку ее появления в списках Exports', первая подпрограмма в первом списке получает индекс 1, следующая — 2 и т.д. Программист может изменить умалчиваемую индексацию и явно указать индекс подпрограммы, добавив за ее именем в списке Exports слово index та. целое число без знака в диапазоне от 1 до 32767:

Expots

MyFunc index 1, MyProc index 2;

Во избежание возможной путаницы с индексацией советую явно задавать индексы всем экспортируемым подпрограммам1.

Программист может определить внешнее имя экспортируемой подпрограммы отличным от ее настоящего имени. Для этого в списке Exports добавляется слово name и внешнее имя в апострофах:

Exports

MyFunc index 1 name 'NEWFUNC';

Обратите внимание: указываемое в апострофах внешнее имя должно состоять из заглавных букв. Если в приведенном выше примере задать ' NewFunc', вызывающая программа не сможет найти функцию MyFunc ни по имени, ни по индексу! По умолчанию ВР создает внешнее имя совпадающим с настоящим, но преобразует его буквы к заглавным.

Вызывающая программа может ссылаться или на имя экспортируемой подпрограммы, или на ее индекс. При вызове по имени программа про—

1 Мною замечено, что ВР начинает умалчиваемую индексацию не с 1, а с 2, что может существенно повлиять на использование DLL. Более того, даже если первой подпрограмме явно присвоить индекс 1, следующая за ней подпрограмма получит умалчивоемый индекс 3, d не 2.

сматривает имена в таблице имен в поисках нужного. Так как имена могут состоять из длинных наборов символов и самих имен в таблице может быть много, процесс поиска имени существенно медленнее, чем процесс поиска индекса. Поэтому опытные программисты предпочитают ссылаться не на имя, а на индекс подпрограммы. Тем не менее, нельзя исключить возможность того, что программа будет вызывать DLL—подпрограмму по имени^ В этом случае затраты времени на поиск можно заметно сократить, если указать в списке Exports слово resident:

Exports

MyFunc index 1 name 'NEWFUNC' resident;

Информация о подпрограмме, экспортируемой с признаком resident, сохраняется в памяти во все время использования библиотеки.

Замечу, что в отличие от модулей ВР не компилирует DLL автоматически в режимах MAKE или BUILD, т.к. справедливо рассматривает ее как другую программу, никак не связанную в момент компиляции с основной программой.

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

{$N+,E+} {Используем сопроцессор для типа Single} Library Complex;

type

TComplex = record Re, Im: Single

end;

Procedure CmplxAdd(x, y: TComplex; var z: TComplex); Export;

begin

z.Irn := x.Im + y.Im;

z . Re : = x. Re + у. Re end;

Procedure CmplxSub(x, y: TComplex; var z: TComplex); Export;

begin

z.Im := x.Im - y.Im;

z. Re : = x. Re - у. Re end;

Procedure CmplxMul(x, y: TComplex; var z: TComplex); Export;

begin

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

z.Im := x.Re * y.Im - x.Im * y.Re end;

Программирование для защищенного режима 235

Procedure CmplxDiv(x, у: TComplex; var z: TComplex); Export;

var

zz: Single;

begin

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

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

z.Im := (x.Re * y.Im - x.Im * y.Re)/zz end;

Exports

CmplxAdd index 1 name 'ADD' resident,

CmplxSub index 2,

CmplxMul index 3,

CmplxDiv index 4;

begin end.

 

Глава 9

Оглавление 

На первую страницу

Rambler's Top100 Rambler's Top100
PROext: Top 1000

(с)Все права защищены

По всем интересующим вопросам прошу писать на электронный адрес

Hosted by uCoz