![]() |
|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
![]() |
|
Опции темы | Поиск в этой теме |
![]() |
#1 |
Laravel/Vue expert
Старожил Подтвердите свой е-майл
Регистрация: 08.08.2007
Сообщений: 2,832
|
![]()
Когда-то как только начал изучать Дельфи, возник вопрос о создании динамически подключаемых библиотек, не ActiveX, а native-dll. Например, на Visual Basic это сделать сложно, теоретически (да и практически, юзая ассемблерные вставки) - можно, но на Дельфи все проще. Эта статья, думаю, пригодится не одному начинающему дельфисту-испытателю, так что если на то позволяет время и желание - советую испытать все на себе.
![]() Введение В связи с бурным развитием технологий программирования, все больше людей сталкиваются с проблемой наращивания возможностей своих программ. Данная статья посвящена именно этому вопросу, а именно - программирование DLL в Borland Delphi. Кроме того, так как мы затронем вопросы по использованию библиотек DLL, то попутно коснемся импортирования функций из чужих DLL (в том числе и системных, т.е. WinAPI). Области применения DLL Итак, зачем же нужны библиотеки DLL и где они используются?.. Перечислим лишь некоторые из областей их применения: Отдельные библиотеки, содержащие полезные для программистов дополнительные функции. Например, функции для работы со строками, или же - сложные библиотеки для преобразования изображений. Хранилища ресурсов. В DLL можно хранить не только программы и функции, но и всевозможные ресурсы - иконки, рисунки, строковые массивы, меню, и т.д. Библиотеки поддержки. В качестве примера можно привести библиотеки таких известных пакетов, как: DirectX, ICQAPI (API для ICQ), OpenGL и т.д. Части программы. Например, в DLL можно хранить окна программы (формы), и т.п. Плагины (Plugins). - Вот где настоящий простор для мыслей программиста! Плагины - дополнения к программе, расширяющие ее возможности. Например, в этой статье мы рассмотрим теорию создания плагина для собственной программы. Разделяемый ресурс. DLL (Dynamic Link Library) может быть использована сразу несколькими программами или процессами (т.н. sharing - разделяемый ресурс) Краткое описание функций и приемов для работы с DLL Итак, какие же приемы и функции необходимо использовать, чтобы работать с DLL? Разберем два метода импортирования функций из библиотеки: 1 способ. Привязка DLL к программе. Это наиболее простой и легкий метод для использования функций, импортируемых из DLL. Однако (и на это следует обратить внимание) этот способ имеет очень весомый недостаток - если библиотека, которую использует программа, не будет найдена, то программа просто не запустится, выдавая ошибку и сообщая о том, что ресурс DLL не найден. А поиск библиотеки будет вестись: в текущем каталоге, в каталоге программы, в каталоге WINDOWS\SYSTEM, и т.д. Итак, для начала - общая форма этого приема: implementation function FunctionName(Par1: Par1Type; Par2: Par2Type; ...): ReturnType; stdcall; external 'DLLNAME.DLL' name 'FunctionName' index FuncIndex; // или (если не функция, а процедура): procedure ProcedureName(Par1: Par1Type; Par2: Par2Type; ...); stdcall; external 'DLLNAME.DLL' name 'ProcedureName' index ProcIndex; Здесь: FunctionName (либо ProcedureName) - имя функции (или процедуры), которое будет использоваться в Вашей программе; Par1, Par2, ... - имена параметров функции или процедуры; Par1Type, Par2Type, ... - типы параметров функции или процедуры (например, Integer); ReturnType - тип возвращаемого значения (только для функции); stdcall - директива, которая должна точно совпадать с используемой в самой DLL; external 'DLLNAME.DLL' - директива, указывающая имя внешней DLL, из которой будет импортирована данная функция или процедура (в данном случае - DLLNAME.DLL); name 'FunctionName' ('ProcedureName') - директива, указывающая точное имя функции в самой DLL. Это необязательная директива, которая позволяет использовать в программе функцию, имеющую название, отличное от истинного (которое она имеет в библиотеке); index FunctionIndex (ProcedureIndex) - директива, указывающая порядковый номер функции или процедуры в DLL. Это также необязательная директива. 2 способ. Динамическая загрузка DLL. Это гораздо более сложный, но и более элегантный метод. Он лишен недостатка первого метода. Единственное, что неприятно - объем кода, необходимого для осуществления этого приема, причем сложность в том, что функция, импортируемая из DLL достуна лишь тогда, когда эта DLL загружена и находится в памяти... С примером можно ознакомиться ниже, а пока - краткое описание используемых этим методом функций WinAPI: LoadLibrary(LibFileName: PChar) - загрузка указанной библиотеки LibFileName в память. При успешном завершении функция возвращает дескриптор (THandle) DLL в памяти. GetProcAddress(Module: THandle; ProcName: PChar) - считывает адpес экспоpтиpованной библиотечной функции. При успешном завершении функция возвращает дескриптор (TFarProc) функции в загруженной DLL. FreeLibrary(LibModule: THandle) - делает недействительным LibModule и освобождает связанную с ним память. Следует заметить, что после вызова этой процедуры функции данной библиотеки больше недоступны. |
![]() |
![]() |
![]() |
#2 |
Laravel/Vue expert
Старожил Подтвердите свой е-майл
Регистрация: 08.08.2007
Сообщений: 2,832
|
![]()
Практика и примеры
Ну а теперь пора привести пару примеров использования вышеперечисленных методов и приемов: Пример 1. Привязка DLL к программе {... Здесь идет заголовок файла и определение формы TForm1 и ее экземпляра Form1} Код:
Пример 2. Динамическая загрузка DLL Код:
Ну а теперь разберем непосредственно саму библиотеку DLL: Пример 3. Исходник проекта MYDLL.DPR Код:
В DLL можно размещать не только функции, но и курсоры, рисунки, иконки, меню, текстовые строки. На этом мы останавливаться не будем. Замечу лишь, что для загрузки ресурса нужно загрузить DLL, а затем, получив ее дескриптор, - загружать сам ресурс соотвествующей функцией (LoadIcon, LoadCursor, и т.д.). В этом разделе мы лишь немного затронем размещение в библиотеках DLL окон приложения (т.е. форм в Дельфи). Для этого нужно создать новую DLL и добавить в нее новую форму (File -> New -> DLL, а затем - File -> New Form). Далее, если форма представляет собой диалоговое окно (модальную форму (bsDialog)), то добавляем в DLL следующую функцию (допустим, форма называется Form1, а ее класс - TForm1): |
![]() |
![]() |
![]() |
#3 |
Laravel/Vue expert
Старожил Подтвердите свой е-майл
Регистрация: 08.08.2007
Сообщений: 2,832
|
![]()
Пример 4. Размещение формы в DLL
Код:
Создание плагинов Здесь мы не будем подробно рассматривать плагины, т.к. уже приведенные выше примеры помогут Вам легко разобраться в львиной части программирования DLL. Напомню лишь, что плагин - дополнение к программе, расширяющее ее возможности. При этом сама программа обязательно должна предусматривать наличие таких дополнений и позволять им выполнять свое предназначение. Т.е., например, чтобы создать плагин к графическому редактору, который бы выполнял преобразование изображений, Вам нужно предусмотреть как минимум две функции в плагине (и, соответственно, вызвать эти функции в программе) - функция, которая бы возвращала имя плагина (и/или его тип), чтобы добавить этот плагин в меню (или в тулбар), плюс главная функция - передачи и приема изображения. Т.е. сначала программа ищет плагины, потом для каждого найденного вызывает его опозновательную функцию со строго определенным именем (например, GetPluginName) и добавляет нужный пункт в меню, затем, если пользователь выбрал этот пункт - вызывает вторую функцию, которой передает входное изображение (либо имя файла, содержащего это изображение), а эта функция, в свою очередь, обрабатывает изображение и возвращает его в новом виде (или имя файла с новым изображением). Вот и вся сущность плагина... :-) Вот, собственно все. Надеюсь, студенту, практику-испытателю и кому-либо другому это пригодится. Удачи! ![]() |
![]() |
![]() |
![]() |
#4 |
Delphi/C++/C#
Участник клуба
Регистрация: 29.10.2006
Сообщений: 1,972
|
![]()
Может в блог поместить?
|
![]() |
![]() |
![]() |
#5 |
Laravel/Vue expert
Старожил Подтвердите свой е-майл
Регистрация: 08.08.2007
Сообщений: 2,832
|
![]()
Лично я - не против.
|
![]() |
![]() |
![]() |
#6 |
Александр
Администратор
Регистрация: 28.10.2006
Сообщений: 17,630
|
![]()
Процедура публикации описана тут - http://programmersforum.ru/showthread.php?t=2126
|
![]() |
![]() |
![]() |
![]() |
||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Не запускается дельфи | L_M | Общие вопросы Delphi | 3 | 21.04.2013 07:17 |
дельфи ubuntu 7,04 | igorvek | Помощь студентам | 2 | 06.07.2010 15:39 |
Дельфи DBGrid! | nur | БД в Delphi | 8 | 18.07.2008 11:45 |
двумерка в дельфи | Puffy | Помощь студентам | 4 | 13.05.2008 01:04 |
многопользовательский чат дельфи | ben95 | Помощь студентам | 8 | 02.02.2008 11:59 |