КОМПЬЮТЕРНЫЕ КУРСЫ "ПОИСК"
[Главная страница] [Delphi] [DLL] [Контакты]
Теперь мы попытаемся создать библиотеку DLL, которая будет использовать тип PChar для передачи строковых данных вызывающему приложению. Это приложение показано на рисунке ниже.
Текст диалогового окна MessageDlg, взятый из библиотеки DLL
Сначала нужно создать главное приложение:
После того как вы создадите интерфейс пользователя главного приложения, вы должны будете создать модуль для перечисления языков, которые будут использоваться главным приложением и библиотекой DLL, а затем добавить новый проект библиотеки DLL в проектную группу
Создаем модуль.
Ниже показан код модуля MyTypes, содержащий перечисление языков:
unit MyTypes; interface type TMyLanguage = (mlEnglish, mlGerman, mlCroatian); implementation end.
Если вы захотите организовать передачу указателя PChar (указатель на строку символов типа Char с нулевым символом в конце) между приложением и библиотекой DLL, то нам нужно будет определиться лишь с тем, как управлять памятью для PChar. Далее приведен перечень того, что вы можете делать, а что — нет:
В листинге 1 показано, как производится выделение и освобождение памяти PChar в библиотеке DLL. Листинг содержит две подпрограммы: функцию GetStringData, которая выделяет память и возвращает локализованную строку, и процедуру FreeStringData, которую необходимо использовать для освобождения памяти, выделенной функцией GetStringData.
Листинг 1. Подпрограммы, управляющие памятью в библиотеке DLL
library LanguageLib;
uses
SysUtils,
Classes, MyTypes;
const
STRING_DATA: array[TMyLanguage] of string = ('Good morning', 'Guten Morgen',
'Dobro jutro.');
{ Возвращаем локализованную строку }
function GetStringData(Language: TMyLanguage): PChar;
begin
{ Выделяем память для строки и символа #0 }
GetMem(Result, Length(STRING_DATA[Language]) + 1);
{ Функция StrPCopy копирует строку в строку с нулевым символом в конце }
StrPCopy(Result, STRING_DATA[Language]);
end;
{ Эта подпрограмма используется для освобождения указателей PChar,
выделенных функцией GetStringData }
procedure FreeStringData(Data: PChar);
begin
FreeMem(Data);
end;
exports GetStringData, FreeStringData;
begin
end.
В листинге 2 показано, как используются подпрограммы GetStringData и FreeStringData в главном приложении.
Листинг 2. Использование подпрограмм GetStringData и FreeStringData для получения локализованной строки из библиотеки DLL
procedure TForm1.RadioGroup1Click(Sender: TObject);
var
DLLHandle: THandle;
stringFunc: function(Language: TMyLanguage): PChar;
freeProc: procedure(Data: PChar);
buffer: PChar;
selectedLang: TMyLanguage;
begin
selectedLang := TMyLanguage(RadioGroup1.ItemIndex);
DLLHandle := LoadLibrary('LanguageLib.dll');
try
{ Находим обе подпрограммы }
stringFunc := GetProcAddress(DLLHandle, 'GetStringData');
freeProc := GetProcAddress(DLLHandle, 'FreeStringData');
if not Assigned(stringFunc) or not Assigned(freeProc) then
//Можно и так
//if (@stringFunc = nil) or (@freeProc = nil) then
MessageDlg('Error Loading DLL!', mtError, [mbOK], 0)
else begin
buffer := stringFunc(selectedLang);
try
MessageDlg(string(buffer), mtInformation, [mbOK], 0);
finally
{ Освобождаем память PChar с помощью подпрограммы DLL FreeStringdata }
freeProc(buffer);
end; // Конец блока try..finally
end; // Конец блока условия if not Assigned
finally
FreeLibrary(DLLHandle);
end; // Конец блока try..finally
end;
Используемая литература:
Иван Хладни. Внутренний мир Borland Delphi 2006.
А.Я. Архангельский. Приемы программирования Delphi на основе
VCL. Версия Delphi 5 - Delphi 2006.