Apr 11

WideString & DLL

В принципе, это не новая заметка, а дубль с форума, на котором я когда-то это уже опубликовал. Но, как говорится, "повторение - мать учения".

Суть в следующем - если вам необходимо передавать строковые данные между программой и dll, то используйте для этого тип WideString. В этом случае вам не придется подключать никакие менеджеры памяти, т.к. для WideString используется не стандартные менеджеры памяти, а системный.

Специальный менеджер сделан для совместимости с COM. И этот менеджер памяти используется один на всех, поэтому WideString можно безопасно передавать и без использования ShareMem, FastShareMem и т.д. - просто в этом случае вы будете терять время на перекодировку в Unicode и обратно. Теперь по поводу выделения/освобождения памяти под WideString.

 

При работе с WideString используются функции SysAllocString/SysReallocString/SysFreeString, которые можно вызвать явно или, как делает Delphi, неявно. Функция SysReAllocStringLen вообще виндовая и не принадлежит самому приложению. Память выделяется и уничтожается внешним, как для DLL так и для программы, менеджером памяти. 

 

Плюс к этому, в отличии от AnsiString, где для определения момента освобождения памяти, занимаемой строкой, используется механизм подсчета ссылок, в WideString всегда используется явно. Т.е. при присваивании wstr1 := wstr2, для AnsiString это будет просто копирование указателя, а для WideString создание новой строки и копирование содержимого wstr2 в созданную строку.

 

Код DLL:

library tstdll;

 

function GetWideString: WideString; stdcall; export;
begin
  Result := 'Какой-то текст.';
end;

 

exports
  GetWideString;

 

begin
end.

 

Код программы:

unit Unit1;

 

interface

 

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, StdCtrls;

 

type

  TForm1 = class(TForm)

    Button1: TButton;

    procedure Button1Click(Sender: TObject);

  private

    { Private declarations }

  public

    { Public declarations }

  end;

 

function GetWideString: WideString; stdcall; external 'tstdll.dll';

 

var

  Form1: TForm1;

 

implementation

 

{$R *.dfm}

 

procedure TForm1.Button1Click(Sender: TObject);

begin

  ShowMessage(GetWideString);

end;

 

end.


Поделитесь вашими мыслями

Поддерживаемые теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>