-
Создание dll
Для создания DLL в Delphi введено зарезервированное слово Library, которым должен начинаться текст библиотеки. За словом Library следует идентификатор библиотеки, он может не совпадать с именем файла. Имя библиотеки определяется именно именем файла, а не идентификатором, следующим за словом Library.
Структура файла DLL повторяет структуру обычной программы с единственным исключением, раздел исполняемых операторов в DLL, играет ту же роль, что и инициирующая часть модуля: операторы этой части выполняются только один раз в момент загрузки библиотеки в память.
В разделе описаний DLL могут объявляться типы (в том числе и классы), константы и переменные, но они остаются скрытыми из вызывающей программы и могут использоваться только внутри DLL. В разделе используется специальный раздел объявления экспортируемых подпрограмм.
Этот раздел начинается зарезервированным словом Exports, за которым через запятую перечисляются имена экспортируемых подпрограмм, например:
library MyDLL;
…
Function MyFunction(…): …;
begin
…
end;
Procedure MyProcedure(…);
begin
…
end;
Exports
MyFunction,
MyProcedure;
Begin
End.
Раздел Exports помогает компилятору и компоновщику создать специальный заголовок DLL_модуля, в котором перечисляются имена подпрограмм и адреса их точек входа. Перечисляемые в списке Exports имена должны быть описаны выше по тексту библиотеки.
-
Пример создания dll
Рассмотрим пример создания динамической библиотеки, включающей в себя 4 процедуры для работы с 3-х мерными векторами.
Для создания библиотечного модуля выполняется команда File/New/Other/DLL Wizard. В результате откроется специальное окно проекта с длинным комментарием, в котором указывается на необходимость вставить ссылку на модуль ShareMem, если библиотека экспортирует длинные строки в параметрах обращения к подпрограммах или как результат функций. Эта ссылка должна быть первой в предложении Uses.
library VectorDLL;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
SysUtils,
Classes;
{$R *.res}
Type
TVector3=record
X,Y,Z: Real;
end;
Function SummaryV(a,b: TVector3): TVector3; stdcall;
begin
Result.X:=a.X+b.X;
Result.Y:=a.Y+b.Y;
Result.Z:=a.Z+b.Z;
end;
Function DifferenceV(a,b: TVector3): TVector3; stdcall;
begin
Result.X:=a.X-b.X;
Result.Y:=a.Y-b.Y;
Result.Z:=a.Z-b.Z;
end;
Function MultiplicationV(a,b: TVector3): Real; stdcall;
begin
Result:=a.X*b.X+a.Y*b.Y+a.Z*b.Z;
end;
Function AbsV(a: TVector3): Real; stdcall;
begin
Result:=sqrt(sqr(a.X)+sqr(a.Y)+sqr(a.Z));
end;
Function CosAngleV(a,b: TVector3): Real; stdcall;
begin
Result:=MultiplicationV(a,b)/(AbsV(a)*AbsV(b))
end;
Exports
SummaryV name 'SummaryV1',
DifferenceV ,
MultiplicationV ,
CosAngleV ;
begin
end.
Все функции созданной библиотеки используют директиву stdcall (также можно использовать директиву safecall), которая обеспечивает совместимость новых функций с функциями API 32-разрядных версий Windows. Если не применять указанную директиву, то будет использоваться более эффективное соглашение реализуемое директивой register, но обращение к созданной библиотеке из программ, написанных на других языках программирования, в общем случае станет невозможным.
Для использования подпрограмм из DLL необходимо описать их как внешние, добавив за словом External имя библиотеки в апострофах:
Procedure MyProc; External ‘MyDLL.dll’;
Подпрограмма вызывается по имени или по индексу. В указанном примере процедура вызывается по имени, если нужно сослаться на индекс, за именем подпрограммы указывается слово Index и сам индекс.
