TURBO PASCAL

Новости

Программы   

Turbo Pascal 

Игры

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

Странности

FAQ

Ссылки

Форум

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

Рассылка

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

Об авторе

 

 

9.5.2. Использование DLL

Для использование подпрограмм из DLL необходимо описать их как внешние, добавив за словом External имя библиотеки в апострофах:

Procedure MyProc; Far; External 'MyDLL';

Обратите внимание: перед External нало обязательно указать Far. в противном случае компилятор потребует поставить точку с запятой после слова External. Как уже говорилось, подпрограмма вызывается по имени или по индексу. В нашем примере из библиотеки MyDLL вызывается подпрограмма с внешним именем 'MYPROC'. Если нужно сослаться на индекс подпрограммы, за именем библиотеки указывается слово index и индекс:

Procedure MyProc; Far; External 'MyDLL' index 2;

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

Procedure MyProc; Far; External 'MyDLL' Name 'ExtName';

В это варианте предполагается, что экспортируется процедура с внешним именем ' EXTNAME'.

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

В следующей программе используется библиотека Complex, описанная на предыдущей странице. {$N+,E+} type

TComplex = record Re, Im: Single

end;

Procedure Add(x, y: TComplex; var z: TComplex); Far;

External 'Complex' ;

Procedure Sub(x, y: TComplex; var z: TComplex); Far;

External 'Complex' index 3;

Procedure Mul(x, y: TComplex; var z: TComplex); Fae;

External 'Complex' Index 4;

Procedure CDiv(x, y: TComplex; var z: TComplex); Far;

External 'Complex' name 'CmplxDiv';

var

a,b,c: TComplex;

begin

{Исходные комплексные числа: 1+li, 1+21}

a. Re := 1;

а. Im : = 1 ;

b.Re := 1;

b.Im := 2;

Add(a,b,с);

WriteLn('Сложение : ', с.Re:3:0, c.Im:4:0,'i');

Sub (a,b,с) ;

WriteLn('Вычитание: ', c.Re:3:0, c.Im:4:0,'i');

Mul (a,b,c) ;

WriteLn('Умножение: ', c.Re:3:0, c.Im:4:0,'i');

CmplxDiv(a,b,с);

WriteLn('Деление : ', c.Re:3:l, c.Im:4:1,'i');

end.

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

Программа может загружать DLL и самостоятельно (динамически) с помощью трех функций, входящих в модуль WinAPI: LoadLibrary, CetProcAddress и FreeLibrary. Следующий пример иллюстрирует технику динамической загрузки DLL Complex:

{$N+,E+} Uses WinAPI;

type

TComplex = record Re, Im: Single

end;

TComplexProc = Procedure (x, y: TComplex; var z: TComplex);

var

a, b, c: TComplex;

Add, Sub, Mul, CDiv: TComplexProc;

Handle: Word;

begin

{Исходные комплексные числа: 1+li, 1+2i} a. Re := 1;

a. Im : = 1;

b.Re := 1;

b.Im := 2;

{Загружаем библиотеку COMPLEX.DLL) Handle := LoadLibrary('COMPLEX.DLL');

if Handle = 0 then begin

WriteLn('He найдена библиотека COMPLEX.DLL');

Halt end;

{Определяем адреса процедур. Три первые вызываем по

индексу, четвертую - по имени. При вызове по индексу

младшее слово PChar должно содержать индекс,

поэтому делаем приведение типов:} @Add := GetProcAddress(Handle,PChar(Longint(1)));

@Sub := GetProcAddress(Handle,PChar(Longint(2)));

@Mul := GetProcAddress(Handle,PChar(Longint(3) ));

@CDiv := GetProcAddress(Handle,'CmplxDiv');

{Используем библиотеку} Add(a,b,с) ;

WriteLn('Сложение : ', с.Re:3:0, с.Im:4:0,'i') ;

Sub(a,b,с) ;

WriteLn('Вычитание: ', c.Re:3:0, c.Im:4:0,'i');

Mul(a,b,c) ;

WriteLn('Умножение: ', c.Re:3:0, c.Im:4:0,'i');

CDiv(a,b,c) ;

WriteLn('Деление : ', c.Re:3:1, c.Im:4:1,'i');

{После использования удаляем библиотеку из памяти} FreeLibrary(Handle) end.

При вызове DLL—подпрограмм в большинстве случаев бывает необходимо передавать структурированные параметры типа записей, как тип TComplex в предыдущем примере. Поскольку DLL не могут экспортировать типы, приходится объявлять эти типы в вызывающей программе. Если Вы часто обращаетесь в своих программах к той или иной DLL, удобно создать интерфейсный модуль, содержащий объявления как подпрограмм, так и связанных с ними типов. Например:

Unit Cmplx;

{$N+,E+}

Interface type

TComplex = record

Re, Im: Single end;

Procedure Add (x, y: TComplex; var z: TComplex);

Procedure Sub (x, y: TComplex; var z: TComplex);

Procedure Mul (x, y: TComplex; var z: TComplex);

Procedure CDiv(x, y: TComplex; var z: TComplex);

Implementation Procedure Add; External 'Complex' index 1;

Procedure Sub; External 'Complex' index 2;

Procedure Mul; External 'Complex' index 3;

Procedure CDiv; External 'Complex' index 4;

end.

Такой интерфейсный модуль существенно упрощает разработку основной программы:

{$N+,E+} Uses Cmplx;

var

a,b,c: TComplex;

begin

a. Re := 1;

a. Im := 1;

b.Re := 1;

b.Im := 2;

Add(a,b,c) ;

WriteLnCСложение : ', с.Re:3:0, с.Im:4:0,'i');

Sub (a,b,c);

WriteLn('Вычитание: ', с.Re:3:0, с.Im:4:0,'i') ;

Mul(a,b,с);

WriteLn('Умножение: ', с.Re:3:0, с.Im:4:0,'i') ;

CDiv(a,b,с) ;

WriteLn('Деление : ', с.Re:3:1, с.Im:4:1,'i') ;

end.

 

Глава 9

Оглавление 

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

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

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

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

Hosted by uCoz