Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

FreeAbout(f);



f:=ShowAbout(Handle); end;

Здесь идёт проверка, если f больше нуля, то надо освободить память от старого окна, а потом пытаться создавать новое.

По событию OnClose для главной формы тоже не помешает вызвать процедуру освобождения памяти. Если программа закрывается, то окно из библиотеки уж точно уже не понадобится, значит, переменную f можно проверять на 0 и если там большее значение, то освобождать память.

На компакт диске находится пример, в котором уже реализовано всё сказанное и ты можешь увидеть этот код своими глазами и проверить его в действии.

На компакт диске, в директории \Примеры\Глава 18\NoModal ты можеш ь увидеть приме р это й программы.

18.6. Явная загрузка библиотек.

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

скорости (не сильно, но всё же), а функции из библиотеки могут вообще не понадобиться за всё время выполнения программы. Во-вторых, тебе может понадобиться поставлять программу в укороченном варианте без некоторых функций (без каких-либо dll файлов), но это не получиться, потому что программа на этапе загрузке будет выдавать ошибку о том, что библиотека не найдена.

От всего этого можно избавиться, если использовать явную загрузку библиотеки в определённый момент. Для этого надо немного попотеть.

Давай в предыдущем нашем примере будем использовать явную загрузку библиотеки для вызова функции ShowAbout. В принципе, если уже делать явную загрузку, то для всех функций и процедур библиотеки, потому что если ты оставишь хотя бы одну неявной, то библиотека всё равно будет грузиться на этапе старта программы. Но для примера я взял только одну функцию, а процедуру попробуй перевести на явную загрузку сам. Тем более, что для этого не надо делать много изменений.

Итак, загружай приложение, написанное в прошлой части, которое использует динамическую библиотеку. В основном модуле убирай объявления функции ShowAbout, чтобы ничего не осталось. Теперь в разделе type пиши объявление нового типа:

ShowA=function (Handle: THandle):LongInt;stdcall;

Здесь я объявляю новый тип ShowA, который равен функции с параметрами фкнуции ShowAbout из динамической библиотеки. Параметры должны быть точными, как при объявлении, иначе могут возникнуть проблемы.

Всё, этого достаточно. Теперь нужно переходить к обработчику события OnClick для первой кнопки, где мы показывали окно. Подкорректируй уже имеющийся код до следующего:

procedure TForm1.Button1Click(Sender: TObject);

var dllHandle:THandle; sa:ShowA;

begin if f>0 then FreeAbout(f);

dllHandle:=LoadLibrary('ProjectDLL.dll');

if dllHandle=0 then exit;// Библиотека не загрузилась

@sa:=GetProcAddress(dllHandle, 'ShowAbout');

if @sa=nil then exit;// Функция не найдена

f:=sa(Handle); FreeLibrary(dllHandle); end;

Здесь у меня объявлено две локальные переменные:
dllHandle – здесь будет храниться указатель на загруженную библиотеку.
sa – имеет тип ShowA, т.е. тип функции из библиотеки.

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

Дальше, я вызываю функцию LoadLibrary. Эта функция загружает указанную в качестве параметра динамическую библиотеку в память. Результатом выполнения функции является указатель на загруженную библиотеку. Этот указатель я сохраняю в переменной dllHandle. После этого нужно проверить, если указатель dllHandle равен нулю, то библиотека не загрузилась.

Теперь нам надо получить адрес функции ShowAbout в загруженной памяти, чтобы мы могли выполнить процедуру. Для этого я вызываю функцию GetProcAddress. Процедуре нужно передать два параметра:

1. 1. Указатель на загруженную библиотеку.

2. 2. Имя искомой процедуры.

Результатом будет адрес искомой функции, и я его сохраняю по адресу переменной @sa. Теперь sa указывает на адрес, по которому загружена библиотека ShowAbout. Единственное, что надо проверить – корректность адреса. Если он равен nil, то процедура не найдёна (возможно, это старая версия библиотеки или неправильно указано имя).

Если всё нормально, то я вызываю функцию через переменную f:=sa(Handle), почти так же, как это делалось раньше. Результат выполнения функции сохраняется в переменной f.

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

На компакт диске, в директории \Примеры\Глава 18\CallFunc ты можеш ь увидеть приме р это й программы.

18.7. Точка входа.

ы наверно заметил, что в исходнике библиотеки есть begin и end не относящиеся к ни одной из процедур или функций. Код, описанный здесь, выполняется самым первым при загрузке библиотеки в память. Но зачем это

нужно? Здесь можно было бы инициализировать какие-то переменные, но библиотека не может храниться их.

В библиотеках есть одна глобальная переменная, которая существует всегда и её имя DLLProc. Это не просто переменная, а указатель на процедуру. По умолчанию он равен nil, но если сюда записать адрес реальной процедуры, то эта процедура может вызываться на определённые события, происходящие в библиотеке. В процедуре можно вылавливать следующие события:

DLL_PROCESS_ATTACH – это событие генерируется при загрузке библиотеки.

DLL_PROCESS_DETACH – это событие генерируется при выгрузке библиотеки.

DLL_THREAD_ATTACH – при создании нового потока.

DLL_THREAD_DETACH – при отключении нового потока.

Честно скажу, что всё это тебе может и не пригодиться, но я всё же дам маленький пример, чтобы ты увидел, как это работает.

Открываем нашу библиотеку, написанную в прошлой части. Теперь добавляем в неё следующий код:





Дата публикования: 2014-11-28; Прочитано: 228 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.007 с)...