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.