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