Перенос кода с использованием DLL
Перенос кода с использованием DLL
Создание DLL в Delphi (экспорт)
Для программирования DLL Delphi предоставляет ряд ключевых слов и правил синтаксиса. Главное - DLL в Delphi такой же проект как и программа.
Рассмотрим шаблон DLL:
library MyDll;
uses
<используемые модули>;
<объявления и описания функций>
exports
Рекомендуемые материалы
<экспортируемые функции>
begin
<инициализационная часть>
end.
Имя файла проекта для такого шаблона должно быть MYDLL.DPR.
!!!! К сожалению, в IDE Delphi автоматически генерируется только проект программы, поэтому Вам придется проект DLL готовить вручную. В Delphi 2.0 это неудобство устранено.
Как и в программе, в DLL присутствует раздел uses. Инициализационная часть необязательна. В разделе же exports перечисляются функции, доступ к которым должен производится из внешних приложений.
Экспортирование функций (и процедур ) может производится несколькими способами:
по номеру (индексу);
по имени.
В зависимости от этого используется различный синтаксис:
{экспорт по индексу}
procedure ExportByOrdinal; export;
begin
.....
end;
exports
ExportByOrdinal index 10;
{экспорт по имени}
procedure ExportByName; export;
begin
.....
end;
exports
ExportByName name 'MYEXPORTPROC'; { имя для экспорта может не совпадать с именем функции ! }
Так как в Windows существует понятие "резидентных функций" DLL, то есть тех функций, которые находятся в памяти на протяжении всего времени существования DLL в памяти, в Delphi имеются средства для организации и такого рода экспорта:
exports
ExportByName name 'MYEXPORTPROC' resident;
Стоит отметить тот факт, что поиск функций, экспортируемых по индексу, производится быстрее, чем при экспорте по имени. С другой стороны, экспорт по имени удобнее, особенно если Вы периодически дополняете и расширяете набор экспортируемых из DLL функций, при гарантии работы приложений, использующих DLL, и не хотите специально следить за соблюдением уникальности и соответствия индексов.
Если же Вы будете экспортировать функции следующим образом:
exports
MyExportFunc1,
MyExportFunc2,
.....;
то индексирование экспортируемых функций будет произведено Delphi автоматически, а такой экспорт будет считаться экспортом по имени, совпадающему с именем функции. Тогда объявление импортируемой функции в приложении должно совпадать по имени с объявлением функции в DLL. Что же касается директив, накладываемых уже на импортируемые функции, то об этом мы поговорим ниже.
Использование DLL в Delphi (импорт)
Для организации импорта, т.е. доступа к функциям, экспортируемым из DLL, так же как и для их экспорта, Delphi предоставляет стандартные средства.
Для показанных выше примеров, в Вашей программе следует объявить функции, импортируемые из DLL таким образом:
{ импорт по специфицированному имени }
procedure ImportByName;external 'MYDLL' name 'MYEXPORTPROC';
{ импорт по индексу }
procedure ImportByOrdinal; external 'MYDLL' index 10;
{ импорт по оригинальному имени }
procedure MyExportFunc1; external 'MYDLL';
Этот способ называется статическим импортом.
Как Вы могли заметить, расширение файла, содержащего DLL, не указывается - по умолчанию подразумеваются файлы *.DLL и *.EXE. Как же тогда быть в случае, если файл имеет другое расширение (например, как COMPLIB.DCL в Delphi), или если требуется динамическое определение DLL и импортируемых функций (например, Ваша программа работает с различными графическими форматами, и для каждого из них существует отдельная DLL.)?
Для решения такого рода проблем Вы можете обратиться напрямую к API Windows, используя, так называемый, динамический импорт:
uses
WinTypes, WinProcs, ... ;
type
TMyProc = procedure ;
var
Handle : THandle;
MyImportProc : TMyProc;
begin
Handle:=LoadLibrary('MYDLL');
if Handle>=32 then { if <=32 - error ! }
begin
@MyImportProc:=GetProcAddress(Handle,'MYEXPORTPROC');
if MyImportProc<>nil then
Ещё посмотрите лекцию "40. Требования безопасности к технологическим процессам" по этой теме.
...... {using imported procedure}
end;
FreeLibrary(Handle);
end;
!!! Синтаксические диаграммы объявлений экспорта/импорта, подмена точки выхода из DLL, и другие примеры, Вы можете найти в OnLine Help Delphi, Object Pascal Language Guide, входящему в Borland RAD Pack for Delphi, и, например, в книге "Teach Yourself Delphi in 21 Days".
Если не говорить о генерируемом компилятором коде (сейчас он более оптимизирован), то все правила синтаксиса остались те же , что и в Borland Pascal 7.0