Аватар для STRATEG
1174 / 480 / 83
Регистрация: 04.03.2010
Сообщений: 1,019

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

07.05.2010, 14:03. Показов 104319. Ответов 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
70
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.05.2010, 14:03
Ответы с готовыми решениями:

Основы для создания бота для сайта
Есть небольшое знание js, но, как ни парадаксально нет знания даже основ для понимания по созданию бота. Не могли бы вы их написать, то...

Использование String Tables в .dll(.dll.mui) (Для VB .NET)
Здравствуйте. Нужно извлечь(а потом запоковать) таблицу строк(string tables ). Допустим есть файл explorerframe.dll.mui из...

Ошибка об отсутствии MSVCP140D.dll, ucrtbased.dll, CONCRT140D.dll, VCRUNTIME140D.dll
Добрый день, товарищи. Возникла проблема. Делаю программу с использованием openCV 3.1 на Visual Studio 2013. При компиляции выдает ошибку...

3
 Аватар для Vovan-VE
13210 / 6599 / 1041
Регистрация: 10.01.2008
Сообщений: 15,069
07.05.2010, 16:13
Думаю, немного суховато написано. Расчитано на копи-паст и даже поверхностно не раскрывает сути DLL.

<Mawrat: Всё сразу не напишешь. Тема остаётся открытой - т. е. желающие могут добавлять свои посты с материалами.>
4
3 / 3 / 0
Регистрация: 06.10.2009
Сообщений: 32
30.10.2010, 10:08
Вопрос можно?
В 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
8 / 8 / 0
Регистрация: 02.08.2010
Сообщений: 63
26.11.2010, 21:45
Хотелось бы подробного рассмотрения Хуков, и вообще, добавьте пожалуйста список задач, в которых без ДЛЛ ну никак не обойтись и те задачи, где ДЛЛ использовать предпочтительнее...

<STRATEG:Хорошо. Материал будет добавлен. К сожалению, только в [незнаю каком] году. Если что-то срочное обращайтесь в личку. >
3
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.11.2010, 21:45
Помогаю со студенческими работами здесь

Нужна Dll для exe msvbm70b.dll
Привет у меня есть exe просит Dll msvbm70b.dll, пришлите плз. Спасибо!

Основы Java (для новичка)
Здравствуйте. Я месяц изучал Си, разбираюсь в синтаксисе, могу написать простую программу.:umnik: Начал изучать язык Java и у меня...

Metasploit основы для новичка
Интересует в частности где брать уязвимости как их устанавливать и как с ними работать. Желательно подбросить ссылки на форум или сайт,...

Основы Питона для Notepad++
Здравствуйте. Недавно мне очень помогли на этом форуме с парсером для обработки имён, написанном на Python. Теперь я хочу сам освоить...

Pjsip4net основы для работы с библиотекой
Необходима помощь тех кто работал с данной библиотекой по IP телефонии. Простой пример или какое-либо пояснение, а то уже достаточно долго...


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

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

Новые блоги и статьи
И решил я переделать этот ноут в машину для распределенных вычислений
Programma_Boinc 09.11.2025
И решил я переделать этот ноут в машину для распределенных вычислений Всем привет. А вот мой компьютер, переделанный из ноутбука. Был у меня ноут асус 2011 года. Со временем корпус превратился. . .
Мысли в слух
kumehtar 07.11.2025
Заметил среди людей, что по-настоящему верная дружба бывает между теми, с кем нечего делить.
Новая зверюга
volvo 07.11.2025
Подарок на Хеллоуин, и теперь у нас кроме Tuxedo Cat есть еще и щенок далматинца: Хочу еще Симбу взять, очень нравится. . .
Инференс ML моделей в Java: TensorFlow, DL4J и DJL
Javaican 05.11.2025
Python захватил мир машинного обучения - это факт. Но когда дело доходит до продакшена, ситуация не так однозначна. Помню проект в крупном банке три года назад: команда data science натренировала. . .
Mapped types (отображённые типы) в TypeScript
Reangularity 03.11.2025
Mapped types работают как конвейер - берут существующую структуру и производят новую по заданным правилам. Меняют модификаторы свойств, трансформируют значения, фильтруют ключи. Один раз описал. . .
Адаптивная случайность в Unity: динамические вероятности для улучшения игрового дизайна
GameUnited 02.11.2025
Мой знакомый геймдизайнер потерял двадцать процентов активной аудитории за неделю. А виновником оказался обычный генератор псевдослучайных чисел. Казалось бы - добавил в карточную игру случайное. . .
Протоколы в Python
py-thonny 31.10.2025
Традиционная утиная типизация работает просто: попробовал вызвать метод, получилось - отлично, не получилось - упал с ошибкой в рантайме. Протоколы добавляют сюда проверку на этапе статического. . .
C++26: Read-copy-update (RCU)
bytestream 30.10.2025
Прошло почти двадцать лет с тех пор, как производители процессоров отказались от гонки мегагерц и перешли на многоядерность. И знаете что? Мы до сих пор спотыкаемся о те же грабли. Каждый раз, когда. . .
Изображения webp на старых x32 ОС Windows XP и Windows 7
Argus19 30.10.2025
Изображения webp на старых x32 ОС Windows XP и Windows 7 Чтобы решить задачу, использовал интернет: поисковики Google и Yandex, а также подсказки Deep Seek. Как оказалось, чтобы создать. . .
Passkey в ASP.NET Core identity
stackOverflow 29.10.2025
Пароли мертвы. Нет, серьезно - я повторяю это уже лет пять, но теперь впервые за это время чувствую, что это не просто красивые слова. В . NET 10 команда Microsoft внедрила поддержку Passkey прямо в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru