Библиотека динамической компоновки — это набор процедур и функций, которые могут вызываться приложениями и другими библиотеками DLL. Она содержит общедоступный код или ресурсы. Поскольку код DLL использует технологию совместного использования памяти, Windows также предоставляет DLL некоторые более высокие разрешения в некоторых местах, поэтому DLL может реализовать некоторые функции, которые не могут быть достигнуты обычными программами, например, реализация Windows HOOK, ISAPI и т. д. В то же время DLL также предоставляет удобный способ совместного использования кода между разными языками. Поэтому DLL широко используется в программировании. В этой статье рассказывается, как создавать и использовать DLL в Delphi.
один. Механизм разделения памяти библиотеки DLL
С точки зрения использования DLL и модуль очень похожи. Они оба могут вызываться другими модулями проекта, но существуют различия в их внутренних механизмах реализации. Если программный модуль использует оператор using для ссылки на модуль, то при компиляции модуля он скомпилирует его вместе с модулем и свяжет скомпилированный исполняемый код с программным модулем. Вот как программный модуль может это сделать. Причина вызова. процедуры и функции в указанном модуле. Когда на один и тот же модуль ссылаются несколько проектов, каждый проект содержит исполняемый код модуля. Когда несколько проектов, содержащих этот модуль, выполняются одновременно, исполняемый код модуля будет обновляться несколько раз с разными проектами. в память, что приводит к пустой трате ресурсов памяти. DLL отличается, даже если она вызывается определенным проектом, она все равно независима после компиляции. То есть после компиляции библиотека DLL образует отдельный исполняемый файл и не связана ни с каким другим исполняемым файлом. Библиотека DLL не подчиняется конкретному проекту. Когда несколько проектов вызывают одну и ту же библиотеку DLL, только первый проект переносит библиотеку DLL в память. Остальные проекты не переносят одну и ту же библиотеку DLL повторно в память, а читают из нее. та же общая область памяти. Более того, код исполнения DLL динамически переносится во время работы программы, а не переносится в память вместе со всем проектом во время работы программы. Это может устранить недостатки, связанные с тем, что один и тот же код занимает память в нескольких местах.
2. Создание библиотеки DLL в Delphi.
В среде Delphi написание DLL мало чем отличается от написания обычного приложения. Фактически, написание функций DLL как основного тела DLL не требует каких-либо других специальных средств, за исключением различий в управлении памятью и ресурсами.
Формат общих файлов проекта:
Название проекта ПРОГРАММЫ;
использует пункт;
Тело программы
Формат файлов проекта DLL:
название библиотечного проекта;
использует пункт;
пункт об экспорте;
Тело программы
Между ними есть два основных различия:
1. Обычно в заголовке файлов проекта используется ключевое слово program, а в заголовке файлов проекта DLL — ключевое слово библиотеки. Различные ключевые слова указывают компилятору генерировать разные исполняемые файлы. Ключевое слово program используется для создания файла .exe, а ключевое слово библиотеки используется для создания файла .dll;
2. Если DLL хочет экспортировать функции или процедуры для использования другими приложениями, эти функции или процедуры должны быть перечислены в разделе экспорта. Сами эти функции или процедуры должны быть скомпилированы с использованием директивы компиляции экспорта.
Выберите новый пункт... в файле главного меню Delphi, дважды щелкните значок DLL во всплывающем окне, и структура исходного модуля DLL будет автоматически предоставлена следующим образом:
Библиотечныйпроект1;
{...аннотация...}
использует
SysUtils, Классы;
начинать
конец.
Затем вы можете добавить определения процедур и функций, которые хотите реализовать в DLL, между USES и Begin, и использовать экспорт и экспорт для их экспорта, чтобы другие модули могли ссылаться на них. Добавьте код инициализации между началом и концом. используется для инициализации переменных DLL. Следует отметить, что даже если код инициализации отсутствует, начало и конец нельзя опустить, как в следующем примере:
библиотекаминмакс;
functionMin(X,Y:Integer):Integer;export;
начинать
еслиX<YthenMin:=XelseMin:=Y;
конец;
functionMax(X,Y:Integer):Integer;export;
начинать
еслиX>YthenMax:=XelseMax:=Y;
конец;
экспорт
Минииндекс1,
Максиндекс2;
начинать
конец.
После компиляции и сохранения как minmax.DLL формируется файл библиотеки DLL.
Доступ к трем библиотекам DLL
Существует два способа доступа к библиотеке DLL: один — статическая ссылка, другой — динамическая ссылка.
Загрузка DLL с использованием метода статической ссылки требует двух вещей: создания модуля ввода для библиотеки DLL и использования USES для подключения модуля ввода к программному модулю, который использует функции DLL. Единственная разница между модулем ввода, созданным для библиотеки DLL, и обычным модулем заключается в том, что процедуры и функции, объявленные в его интерфейсе, не дают реального кода реализации в его части реализации. Вместо этого для объявления процедур и используется ключевое слово external. Функции Детали реализации делегируются внешним модулям DLL.
Синтаксис использования внешней команды следующий:
имя процедуры/функции процедуры/функции; имя модуля externalDLL;
Ниже приведен исходный файл входного модуля testdll.pas, написанный для библиотеки minmax.DLL, созданной выше. Из него мы можем увидеть некоторые различия между входным модулем и общим модулем. Код выглядит следующим образом:
unittestdll;
интерфейс
использует
functionMin(X,Y:Integer):Integer;
functionMax(X,Y:Integer):Integer;
выполнение
functionMin;внешний'minmax.DLL';
functionMax;внешний'minmax.DLL';
конец.
Если приложение хочет вызвать функцию в minmax.DLL, ему нужно только добавить модуль testdll в свой оператор использования.
Для динамической загрузки DLL требуются три функции API Windows. Loadlibrary, Freelibrary и GetprocAddress. Функция loadlibrary используется для загрузки библиотеки DLL. Формат ее вызова следующий:
functionloadlobrary(DLLfileName:Pchar):THandle:
Когда библиотека DLL больше не нужна, следует вызвать функцию FreeLibrary, чтобы освободить ценные ресурсы памяти. Формат вызова следующий:
процедураFreeLibrary (Libmodule:THandle)
Libmodule — это дескриптор библиотеки DLL, полученный вызовом LoadLibrary. В сегменте программы между загрузкой библиотеки DLL с помощью функции loadlobrary и вызовом FreeLibrary для освобождения библиотеки DLL вы можете использовать процедуры и функции библиотеки DLL. Конкретный метод использования: использовать функцию GetprocAddress для получения адреса. функцию в библиотеке DLL. Передайте ее функциональной переменной в программе, а затем используйте эту переменную для вызова функции DLL. Функция GetprocAddress объявляется следующим образом:
functionGetprocAddress(Libmodule:THandle:procname:pchar):TFarProc:
Как показано в следующем примере:
тип
TTimeRec=запись
Второе: целое число;
Минута: целое число;
Час: Целое число;
конец;
TGetTime = процедура (varTime: TTimeRec);
THandle=Целое число;
вар
Время: Ттимерек;
Ручка:Ручка;
GetTime:TGetTime;
...
начинать
Handle:=LoadLibrary('DATETIME.DLL');
еслиHandle<>0then
начинать
@GetTime:=GetProcAddress(Handle,'GetTime');
if@GetTime<>nilthen
начинать
ПолучитьВремя(Время);
сTimedo
WriteLn('Время',Час,':',Минута,':',Секунда);
конец;
Бесплатная библиотека (дескриптор);
конец;
конец;
При вызове динамической библиотеки следует учитывать, что требуемая динамическая библиотека должна находиться в том же каталоге, что и приложение, или в каталоге WindowsSystem.
Библиотеки динамической компоновки — важный способ организации программ в Windows. Использование библиотек динамической компоновки может значительно защитить работу, выполняемую пользователями в различных инструментах разработки и в разные периоды, а также повысить эффективность программирования.