Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Finally




Else

End

Else

End

Try

Begin

Var

Type

TAddFunction = function(K:Integer): Integer: stdcall;

procedure Tform1.Button2Click(Sender:TObject);

Addl: TAddFunction;

HLib: THandle;

N: Integer;

HLib:= 0;

HLib:= LoadLibrary(‘FIrstLib.dll’);

if HLib <> 0 then begin

Add1:= GetProcAddress(HLib, 'CalculateSum');

if Assigned(Add1) then begin

N:= StrToInt(Editl.Text);

N:= Addl(N):

Edit1.Text:= IntToStr(N);

ShowMessage(' CalculateSum was not found');

ShowMessage('Can not load library FirstLib.dll’);

if HLib<> 0 then FreeLibrary(HLib);

end;

end;

Первоначально определяется новый процедурный тип — например, TAddFunction, который имеет тот же самый список параметров и то же самое соглашение о вызовах, что и функция в DLL. Delphi в процессе компиляции приложения никак не может проверить соответствие процедурного типа функции, вызываемой из DLL. Проверка может быть осуществлена только во время выполнения — при несоответствии формальных параметров или неверно указанного соглашения о вызовах происходит крах стека, и программист это очень быстро обнаружит.

Далее в коде приложения вызывается функция LoadLibrary, которая в качестве параметра использует имя библиотеки. После успешной отработки этой функции и загрузки библиотеки в память дескриптор загруженной библиотеки помещается в переменную HLib. Если же не удается найти (или загрузить) библиотеку, то в эту же переменную помещается код ошибки. Для определения факта загрузки библиотеки переменную HLib следует сравнить с нулем. Если библиотека была успешно загружена, то делается попытка найти адрес функции в памяти компьютера путем вызова функции Windows API GetProcAddress, возвращающей адрес функции, имя которой указано во втором параметре GetProcAddress. Если же функция не найдена, возвращается значение nil.

Соответственно, вызов функции Add1 осуществляется, только если она была успешно найдена. Далее, поскольку при загрузке библиотеки были заняты системные ресурсы, их необходимо вновь вернуть системе, выгрузив библиотеку из памяти. Для этого вызывается функция FreeLibrary. При загрузке DLL производится подсчет ссылок — а именно, при каждом успешном обращении к функции LoadLibrary в DLL счетчик ссылок увеличивается на единицу. При каждом вызове функции FreeLibrary счетчик ссылок уменьшается на единицу. Как только счетчик ссылок станет равным нулю, библиотека может быть выгружена из памяти компьютера. Поэтому каждому успешному вызову LoadLibrary должно соответствовать обращение к FreeLibrary — иначе DLL не выгрузится из памяти компьютера до окончания работы приложения. Поэтому перечисленные функции помещены в защищенный блок try...finally...end — это гарантирует вызов функции FreeLibrary, если происходит исключение.

Теперь следует рассмотреть, каким образом загружаемая библиотека размещается в памяти компьютера. При загрузке DLL осуществляется резервирование памяти, необходимое для хранения кода функций. Кроме того, резервируется место для всех глобальных переменных и выполняются секции инициализации в модулях DLL. Если другой процесс также пытается загрузить DLL, то вновь происходит резервирование памяти для хранения глобальных переменных. Однако копирование функций DLL не осуществляется. Другими словами, одна копия функции в памяти обслуживает несколько приложений. Глобальные переменные являются уникальными для каждого приложения, и если одно приложение изменит их значение путем вызова какой-нибудь функции, то другое приложение этого не заметит.

Библиотеки СОМ DLL загружаются только динамически, при обращении клиента к интерфейсу, который находится в данной библиотеке. Для того чтобы библиотека СОМ загружалась сразу же после старта приложения и выгружалась после его окончания (аналог статической загрузки), требуется написание кода, в частности кода вызова функции LockServer для фабрики классов или использования функции CoLoadLibrary.

 

 




Поделиться с друзьями:


Дата добавления: 2014-01-05; Просмотров: 255; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.006 сек.