Отправляет email-рассылки с помощью сервиса Sendsay

Программирование на Delphi

  Все выпуски  

Программирование на DELPHI v3-7 Всё о DLL(Часть 1)


Информационный Канал Subscribe.Ru

ПРОГРАММИРОВАНИЕ НА DELPHI v1-7 Кол-во подписчиков: 6600+

  САЙТ/АРХИВ РАССЫЛКИ ::  НАШИ OFFLINE-ЖУРНАЛЫ   :: ФОРУМ

 Привет вам, дельфяне!

Уважаемые подписчики! В связи с некоторыми проблемами, все ваши письма, отправленные на ящик delphi@goldfaq.ru в период с 03.03.04 по 09.03.04, не дошли до нас(не дошло не одного ответа:((). Приносим свои извинения и просим всех, кто писал, переслать Ваши письма заново.

В этом выпуске:

1)Всё о DLL(Введение)-->
2)
Ответы-->
3)Вопросы-->

СТАТЬИ 

Всё о DLL(Введение)

В связи с бурным развитием технологий программирования, все больше людей сталкиваются с проблемой наращивания возможностей своих программ. Данная статья посвящена именно этому вопросу, а именно - программирование 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 и освобождает связанную с ним память. Следует заметить, что после вызова этой процедуры функции данной библиотеки больше недоступны.

Практика и примеры

 Ну а теперь пора привести пару примеров использования вышеперечисленных методов и приемов:

 Пример 1. Привязка DLL к программе

 {... Здесь идет заголовок файла и определение формы TForm1 и ее экземпляра Form1}

 implementation

 {Определяем внешнюю библиотечную функцию}

 function GetSimpleText(LangRus: Boolean): PChar; stdcall; external 'MYDLL.DLL';

 procedure Button1Click(Sender: TObject);

begin

  {И используем ее}

  ShowMessage(StrPas(GetSimpleText(True)));

  ShowMessage(StrPas(GetSimpleText(False)));

  {ShowMessage - показывает диалоговое окно с указанной надписью; StrPas - преобразует строку PChar в string}

end;

 Теперь то же самое, но вторым способом - с динамической загрузкой:

 Пример 2. Динамическая загрузка DLL

 {... Здесь идет заголовок файла и определение формы TForm1 и ее экземпляра Form1}

 var

      Form1: TForm1;

      GetSimpleText: function(LangRus: Boolean): PChar;

      LibHandle: THandle;

 procedure Button1Click(Sender: TObject);

begin

  {"Чистим" адрес функции от "грязи"}

  @GetSimpleText := nil;

  {Пытаемся загрузить библиотеку}

  LibHandle := LoadLibrary('MYDLL.DLL');

  {Если все OK}

  if LibHandle >= 32 then begin

    {...то пытаемся получить адрес функции в библиотеке}

    @GetSimpleText := GetProcAddress(LibHandle,'GetSimpleText');

    {Если и здесь все OK}

    if @GetSimpleText <> nil then

      {...то вызываем эту функцию и показываем результат}

      ShowMessage(StrPas(GetSimpleText(True)));

  end;

  {И не забываем освободить память и выгрузить DLL}

  FreeLibrary(LibHandle);

end;

 ПРИМЕЧАНИЕ: Следует воздерживаться от использования типа string в библиотечных функциях, т.к. при его использовании существуют проблемы с "разделением памяти". Подробней об этом можно прочитать (правда, на английском) в тексте пустого проекта DLL, который создает Delphi (File -> New -> DLL). Так что лучше используйте PChar, а затем при необходимости конвертируйте его в string функцией StrPas.

Ну а теперь разберем непосредственно саму библиотеку DLL:

Пример 3. Исходник проекта MYDLL.DPR

 library mydll;

 

uses SysUtils, Classes;

 

{Определяем функцию как stdcall}

function GetSimpleText(LangRus: Boolean): PChar; stdcall;

begin

  {В зависимости от LangRus возвращаем русскую (True) либо английскую (False) фразу}

  if LangRus then

    Result := PChar('Здравствуй, мир!')

  else

    Result := PChar('Hello, world!');

end;

{Директива exports указывает, какие функции будут экспортированы этой DLL}

exports GetSimpleText;

begin

end.

НОВЫЕ ОТВЕТЫ


НОВЫЕ ВОПРОСЫ

Напоминаю всем, что свой вопрос вы можете задать по адресу delphi@goldfaq.ru с темой VOPROS

Вопрос #45 от Верушкин Сергей

Привет всем,

Меня интерисует работа реестром в Windows. Как прочитать данные из
опеределйнного ключа и как их записать в TEdit.
И ещё меня интерисует запуск другой программы из Delphi7
 

ОТВЕТИТЬ


Вопрос #46 от Даниил

Как сделать, чтобы моя прога (аналог блокнота) при открытии файла
через конт. меню Windows "Открыть с помощью" его открывала, а не
просто сама запускалась?

ОТВЕТИТЬ


Вопрос #47 от Александр

Здрасте!
Если кто-нибудь знает, как при помощи IdFTP и IdFTPServer (или других вещей Delphi 7) связать два удаленных компьютера через модем (но не через интернет) для передачи файлов, пожалуйста расскажите.

ОТВЕТИТЬ


Вопрос #48 от Шпаковский Алексей

Если кто-ни будь знает, как сделать свой SysTray (в Explorer'е - область рядом с часами), в котором отображались бы
иконки после вызова функции Shell_NotifyIcon, напишите, пожалуйста, хотя бы в общих чертах (какие для этого есть
WinAPI функции). Только не надо мне объяснять, как _запихнуть_ туда иконку, я это и так умею (сам только что ответ
написал). Буду очень признателен.

ОТВЕТИТЬ


Вопрос #49 от Pavel Grigoriev

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

ОТВЕТИТЬ


Вопрос #50 от Евгений Р.

Здравствуйте!
Неожиданно интересные ответы нашел в Вашей рассылке.Может быть и мне кто сможет помочь:
У наследников класса tObject есть метод MethodAddress, который добросовестно определяет наличие метода у объекта и возвращает его адрес (если метод описан в разделе Published):
pProc:=obj.MethodAddress(procName);
Воспользоваться полученным адресом можно только из ассемблера:
asm
mov eax, [obj]
mov edx,[p1]
mov ecx,[p2]
call pProc;
End;
Параметры p1 и p2 - ссылки на параметры процедуры.
Разобраться с этим смог просматривая генерируемый код в отладчике.
Ондако не разобрался: как быть, если у процедуры более 2-х параметров, если параметры размером >4 (например double),
как получить результат функции, можно-ли гдето найти список методов объекта, их параметры.
Зараннее благодарен,
Евгений Рачек.

ОТВЕТИТЬ


Вопрос #51 от Антон Зайцев

Доброго времени суток.
Многие наверное видели программы типа "Говорилка".
Хочу тоже такую программу написать в Delphi.
Намыльте мне пожалуйста документации или дайте ссылку в интернет, где
копать.
Заранее благодарен.

ОТВЕТИТЬ


Вопрос #52 от Ruslan H


Срочно нужна помощь!

1. Как мне запустить приложение на удаленной машине.
2. Как там же его завершить. (Сеть локальная, TCP/IP).

Заранее пасибо!

ОТВЕТИТЬ


Вопрос #53 от lvamail

Всем салют!

Следующий вопрос-проблема:
подскажите код инициализации com-порт для приёма-передачи данных.
Зараннее благодарен.

LVA

ОТВЕТИТЬ


Вопрос #54 от slavak

Недавно делфи начал изучать, возник вопросик. Хочу
прогу написать,
которая считает время когда я в инете. Какая-то функция
есть что-ли?!
ПИШИТЕ ПОДРОБНЕЕ, если компонент необходим, пишите
ссылку. Заранее
Благодарен :)

ОТВЕТИТЬ


Вопрос #55 от Сергей

У меня такой вопрос:
Есть база данных, в Memo- поле заносится текст, как осуществить поиск или фильтрацию по ключевым словам этого поля.

ОТВЕТИТЬ


Вопрос #56 от Даниил

Как реализовать поиск в memo, чтобы работали допфункции (вперед,
назад, с учетом регистра, слово целиком)?

ОТВЕТИТЬ


Вопрос #57 от BLADE

Привет!!!!

Как сделать, чтобы MediaPlayer проигрывал несколько файлов поочереди.

BLADE

ОТВЕТИТЬ


Вопрос #58 от jtarasik

У мене ? таке питання: я хочу свою прогу навчити працювати з
плаг?нами. Як зробити коли дода?ться новий плаг?н в?н додався в
головне меню, ? його можна було запустити.
Заздалег?дь дякую!

ОТВЕТИТЬ


Вопрос #59 от Mail

Всем привет!
Подскажите где в Internet можно найти что-нибудь о DelphiX?
Заранее спасибо!

ОТВЕТИТЬ


Вопрос #60 от Даниил


Приветствую!

Есть ли список аналогов команд VCL для kol'a?

ОТВЕТИТЬ


Вопрос #61 от Boris

Как изменить размер шрифта всплывающей подсказки Hint
По умолчанию размер 8(на некоторых компьютерах очень мелко) , а я хочу сделать 12.

ОТВЕТИТЬ


Ведущий рассылки Angel     Дизайн "LikSoftGroup - Design"  13-ый выпуск



http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу


В избранное