КОМПЬЮТЕРНЫЕ КУРСЫ "ПОИСК"
[Главная страница] [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.