пятница, 9 января 2009 г.

Delphi 2009 и приведение к PAnsiString

Часть winapi функций требуют передачи себе в кач-ве параметров структур с PAnsiChar строками (например mapi). В предыдущих версиях приведение строк посредством PChar(SomeString) работало, используя область памяти выделенную под SomeString, а в 2009 результат PAnsiString(AnsiString(SomeString)), уже как вычисление обычной строки из юникодной, размещается в локальной области памяти, что чревато тем, что старый код может перестать работать на, казалось бы, ровном месте (хотя конечно прямое приведение к pchar тоже имеет кучу особенностей).

Например код приведенный ниже возвращает разные результаты на 2007 и 2009 Делфи

program array_error_test;

{$APPTYPE CONSOLE}

uses
SysUtils,
StrUtils,
Classes;

procedure DoMain;
const
Count = 5;

type
RecType = record
AnString: PAnsiChar;
end;
var
RecArr: array of RecType;
I: Integer;
SomeStrings: TStringList;
begin

SetLength(RecArr, Count);

SomeStrings := TStringList.Create;
try
for I := 0 to Length(RecArr) - 1 do
begin
SomeStrings.Add(DupeString(IntToStr(I), 10));
RecArr[I].AnString := PAnsiChar(AnsiString(SomeStrings[I]));
end;

for I := 0 to Length(RecArr) - 1 do
WriteLn(RecArr[I].AnString);
finally
SomeStrings.Free;
end;
end;

begin
DoMain;
ReadLn;
end.

Комментариев нет: