Форум программистов, компьютерный форум, киберфорум
Наши страницы
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 446, средняя оценка - 4.65
STRATEG
1160 / 466 / 82
Регистрация: 04.03.2010
Сообщений: 1,011
#1

Основы DLL для начинающих - Delphi

07.05.2010, 14:03. Просмотров 67188. Ответов 3
Метки нет (Все метки)

Понимая как начинающему не просто самому понять как создавать динамические библиотеки (Dynamic Link Library),я решил написать эту статью, в которой постараюсь раскрыть основные принципы работы с Dll в Delphi.

Для начала нужно знать почему в некоторых случаях лучше сделать Dll,а не просто Модуль. Возможно в нескольких ваших приложениях окажется одинаковый блок кода, не совсем малых размеров, вы можете сделать Модуль и подключить к каждому проекту, но размер EXE файла будет больше, нежели когда вы создадите одну Dll, и будете её использовать во многих программах. Когда вы работаете с динамической библиотекой, вы значительно экономите память, так как в нее загружается всего один экземпляр Dll для всех программ.
Что же могут Динамические библиотеки:
-Хранить в них звуки,картинки,иконки,курсоры и многое другое
-Использоваться в качестве плагинов (для того чтобы не редактировать сам файл программы)
-Помещать туда диалоговые,простые окна;меню и всевозможные другие ресурсы
-Давать возможность другим программистам использовать вашу библиотеку на других языках


Перейдем от теории к практики.

Напишем Dll, которая будет содержать в себе две математические функции:
1)Вычисление Факториала числа.
2)Нахождение суммы двух чисел.

Для начала нужно создать Dll в дельфи, для этого делаем следующее:
File->New->Other->Dll Wizard
Появится проект вашей новой Dll.

Теперь напишем наши две функции:

Delphi
1
2
3
4
5
6
7
8
9
10
11
function Fucktorial(N:integer):integer;stdcall;
var p:integer;
begin
  for p:=1 to N do N:=N*P; 
  Result :=N;
end;
 
function Symma(a,b:integer):Integer;stdcall;
begin
  Result :=a+b;
end;
После каждой функции вы можете заметить что стоит stdcall,эта деректива предписывает использование стандартных соглашений о вызове функций, конечно это не обязательно.

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

Delphi
1
exports Fucktorial,Symma;
Теперь когда Dll готова, сохраним её под именем Math(Имя конечно может быть любое)
File->Save Project As



Неявная(статическая) загрузка
Осталось создать приложение, которое будет использовать функции нашей Dll
File->New->Application

Для примера я поместил на форму: два TEdit, два TButton, один TLabel

После ключегого слова implementation объявим наши функции таким образом

Delphi
1
2
function Symma(a,b:integer):Integer;stdcall;external 'Math.dll';
function Fucktorial(N:integer):integer;stdcall;external 'Math.dll';
Как можно заметить здесь присутствует незнакомое слово external.Так мы определяем где находится наша функция,и откуда её вызывать.В нашем проекте мы вызываем функции из только что созданной Dll.

Напишем код в наши Button

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//суммирование двух чисел
procedure TForm1.btn1Click(Sender: TObject);
var a,b,c:integer;  //переменные для чисел
begin
 a:=StrToInt(edt1.text);
 b:=StrToInt(edt2.text);
 C:=Symma(a,b);
 lblResult.Caption := 'Результат:' + IntToStr(C);
end;
 
//расчет факториала
procedure TForm1.btn2Click(Sender: TObject);
var N:Integer;
begin
 N:=StrToInt(edt1.text);
 lblResult.Caption := 'Результат:' + IntToStr(Fucktorial(N));
end;
Теперь осталось скомпилировать приложение и можно проверять его работу.

Теперь нужно сказать пару слов о проблемах,которые могут возникнуть.

Ваша Dll должна находиться в следующих местах:рядом с программой,System.Если библиотека не найдена программой в этих местах то вылазиет неприятное сообщение об ошибке.


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



Явная(Динамическая) загрузка
Сейчас мы рассмотрим Динамическую или как еще говорят Явную загрузку библиотек. Она по объему кода конечно больше чем Неявная(статическая) но зато более гибкая.

Возьмем наш прошлый проект,и переделаем под явную(динамическую) загрузку.
Теперь вызов выглядит вот так

Сумма двух чисел:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
procedure TForm1.btn1Click(Sender: TObject);
var
a,b,c:integer;                          //переменные для чисел
dHandle: THandle;                   //Хендл загруженной Dll
Symma: function (a,b:integer):Integer;stdcall;  //описываем нашу функцию
begin
//Symma теперь не на какой участок памити не указывает 
@Symma:=nil;                 
//Пытаемся загрузить Dll
 dHandle:=LoadLibrary('Math.dll');          
//Если загрузили то
 if dHandle<>0 then                 
    begin
    //Найдем адрес нужной функции и присвоим его переменной Symma
    @Symma:=GetProcAddress(dHandle,'Symma');
    //если мы нашли функции в Dll и получили её адрес то             
    if @Symma<>nil then                 
          begin
           a:=StrToInt(edt1.text);
           b:=StrToInt(edt2.text);
           C:=Symma(a,b);           
           lblResult.Caption := 'Результат:' + IntToStr(C);
           end
      else              //если мы  не нашли функцию в Dll
          begin
           lblResult.Caption := 'Результат:Функция не найдена в Dll';                 
          Exit;
          end;
     //выгружаем Dll из памяти
     FreeLibrary(dHandle);  
    end
    else
    begin
       //если Dll не может быть загружена или не найдена
       lblResult.Caption := 'Результат:Библеотека не найдена';            
      Exit;
    end;
end;
Факториал числа:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
procedure TForm1.btn2Click(Sender: TObject);
var N:Integer;
dHandle: THandle;
Fucktorial: function (N:integer):integer;stdcall;
begin
 @Fucktorial:=nil;
 dHandle:=LoadLibrary('Math.dll');  //Грузим Dll
 if dHandle<>0 then    begin
    @Fucktorial:=GetProcAddress(dHandle,'Fucktorial');      
      if @Fucktorial<>nil then                  
          begin
            N:=StrToInt(edt1.text);
            lblResult.Caption := 'Результат:' + IntToStr(Fucktorial(N));
           end
      else
          begin
           lblResult.Caption := 'Результат:Функция не найдена в Dll';       
           Exit;
          end;
      FreeLibrary(dHandle);
    end
    else
    begin
      lblResult.Caption := 'Результат:Библеотека не найдена';       
      Exit;
    end;
 
end;
Вы можете испугаться такого количества кода,по сравнению с неявной загрузкой, но когда вы разберетесь все будет казаться простым.

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

Описание незнакомых функций:
Delphi
1
LoadLibrary (lpLibFileName: PChar): HMODULE;
Назначение:
Загружает Dll в память.
Параметры:
lpLibFileName-Путь к Dll.
Возвращаемое значение :
Ссылка на модуль библиотеки при успешной загрузке, иначе 0 .

Delphi
1
GetProcAddress(hModule: HMODULE; lpProcName: LPCSTR): FARPROC ;
Назначение :
Ищет в библиотеке модуль.
Параметры :
lpProcName-Имя функции
hModule-ссылка на модуль которую возвратила нам функция LoadLibrary
Возвращаемое значение:
Указатель на функцию если он найден в Dll, иначе nil.

Delphi
1
FreeLibrary (hLibModule: HMODULE): BOOL;
Назначение :
Выгружает Dll из памяти.
Параметры:
hLibModule- ссылка на модуль которую возвратила нам функция LoadLibrary
Возвращаемое значение:
True если успешно выгрузили, иначе False

Файлы к статье:
Dll.rar
Неявная(статическая) загрузка.rar
Явная(динамическая) загрузка.rar
Книга с исходниками.rar

Новые файлы:
Обмен текстом.rar
Обмен изображениями.rar
Обмен изображениями + текстом.rar
http://www.cyberforum.ru/delphi/thread47905.html
65
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.05.2010, 14:03
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Основы DLL для начинающих (Delphi):

Рукурсия для начинающих
Подскажите как работает рекурсия... Желательно на простом примере... И с...

Delphi для начинающих
Скажите как в Delphi сделать вложенный список(древовидный список) ?

Компонент для начинающих
Всем привет, знаю что есть какое-то дополнение к Delphi при написании когда...

делфи для начинающих
Вообщем давно хочу выучить делфи. Я свой цели по тихоньку добиваюсь. Есть свои...

Delphi для начинающих
Помогите пожалуйста с кодом. Нужно чтобы при нажатие на кнопку открывался...

3
Vovan-VE
13148 / 6531 / 1038
Регистрация: 10.01.2008
Сообщений: 15,071
07.05.2010, 16:13 #2
Думаю, немного суховато написано. Расчитано на копи-паст и даже поверхностно не раскрывает сути DLL.

<Mawrat: Всё сразу не напишешь. Тема остаётся открытой - т. е. желающие могут добавлять свои посты с материалами.>
4
Yami_Yami
3 / 3 / 3
Регистрация: 06.10.2009
Сообщений: 32
30.10.2010, 10:08 #3
Вопрос можно?
В DLL можно объявлять классы?
если да, то как осуществить

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
uses
  SysUtils,
  Classes;
 
{$R *.res}
 
type
  TClass = class(TObject)
 
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
 
begin
end.
<STRATEG: Никакой разницы объявления классов в Dll и в приложении Win нету. Это грубо говоря вообще одно и тоже. По таким вопросам пишите в личку.>
1
NewbieNoob
8 / 8 / 1
Регистрация: 02.08.2010
Сообщений: 63
26.11.2010, 21:45 #4
Хотелось бы подробного рассмотрения Хуков, и вообще, добавьте пожалуйста список задач, в которых без ДЛЛ ну никак не обойтись и те задачи, где ДЛЛ использовать предпочтительнее...

<STRATEG:Хорошо. Материал будет добавлен. К сожалению, только в [незнаю каком] году. Если что-то срочное обращайтесь в личку. >
3
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.11.2010, 21:45
Привет! Вот еще темы с решениями:

Delphi для начинающих
разработать программу в которой происходит введение двох чисел и исполняется их...

Учебники по Delphi для начинающих
Посоветуйте, пожалуйста, хорошие учебники по Delphi. Думаю, эта тема будет...

DELPHI FAQ для начинающих
]В этой теме будут собраны советы и подсказки для новичков в среде...

совет по Delphi для начинающих
Посоветуйте что нужно изучить на начальных этапах(книги какие?, языки...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Закрытая тема Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru