Отличия строк Delphi и Lazarus.
Модератор: Модераторы
Отличия строк Delphi и Lazarus.
Привествую уважаемых форумчан. Имеется Delphi XE 3 и Lazarus 1.0.8. В программе на лазарус структура записывается в строку, зажимается paszlib и сверху кодируется base64 кодированием. Задача - разобрать эту структуру из строки в программе на Delphi. Собственно - после base64 декодирования строка получается, но никак не хочет распаковываться в zlib.uncompress. Собственно вопрос, каким образом мне подружить строки Delphi со строками Lazarus? Что в в строку может дописывать лазарус, что Delphi не считает декодированную строку валидной?
PS: И на Delphi и на Lazarus используются одинаковые алгоритмы. По условиям задачи нельзя менять вывод строки в Lazarus. Юниты для этого используются одинаковые. DCPBase64 для кодировки, zlib 1.1.2 и paszlib 1.1.2 для сжатия(пробовал и более свежий из Delphi, не помогло).
PS: И на Delphi и на Lazarus используются одинаковые алгоритмы. По условиям задачи нельзя менять вывод строки в Lazarus. Юниты для этого используются одинаковые. DCPBase64 для кодировки, zlib 1.1.2 и paszlib 1.1.2 для сжатия(пробовал и более свежий из Delphi, не помогло).
В Delphi XE 3 есть UnicodeString = String и есть AnsiString.
Я знаю, цимес в том что и в том и в другом случае используется String. Вот я и не пойму, где я туплю.
Добавлено спустя 1 час 4 минуты 33 секунды:
Вообщем косяк был в юните Декодирования Base64. Ему оказывается надо было кормить Ansi?String.
Добавлено спустя 38 минут 6 секунд:
Но хоть теперь результаты строк и одинаковы, что в дельфи, что в лазаре - но Дельфя отчаянно не хочет распаковывать то что ей подали на вход. И тут я уже теряюсь в догадках:)
Добавлено спустя 1 час 4 минуты 33 секунды:
Вообщем косяк был в юните Декодирования Base64. Ему оказывается надо было кормить Ansi?String.
Добавлено спустя 38 минут 6 секунд:
Но хоть теперь результаты строк и одинаковы, что в дельфи, что в лазаре - но Дельфя отчаянно не хочет распаковывать то что ей подали на вход. И тут я уже теряюсь в догадках:)
- Снег Север
- долгожитель
- Сообщения: 3071
- Зарегистрирован: 27.11.2007 15:14:47
- Контактная информация:
В Делфи, начиная с 2009 и выше sting- это WideString!
Приведите примеры кода - дело пойдет быстрее.
В Лазаре строки строятся на базе мультибайтных символов (utf8), в дельфи, начиная с 2009, на базе двухбайтных (unicode).
Откажитесь от строк и работайте с блоками памяти - будет проще.
Также не забывайте про кодировку - в дельфи компилятор автоматически вставляет преобразования, иногда не совсем прозрачно.
В Лазаре строки строятся на базе мультибайтных символов (utf8), в дельфи, начиная с 2009, на базе двухбайтных (unicode).
Откажитесь от строк и работайте с блоками памяти - будет проще.
Также не забывайте про кодировку - в дельфи компилятор автоматически вставляет преобразования, иногда не совсем прозрачно.
Снег Север писал(а):В Делфи, начиная с 2009 и выше sting- это WideString!
Немного не так. В Дельфи начиная с 2009:
String = UnicodeString;
WideString <> UnicodeString, хотя оба типа для уникода.
И так, в связи с тем что пока мои телодвижения не принесли результатов - прилагаю образцы кода. В лазарусе структура, а точнее массив структур пишется следующим образом:
Соответственно на выходе я получаю строку вида:
Затем уже из Delphi начинаю её разбирать:
Функция Base64DecodeStr - из модуля DCPCrypt64.pas; если я запаковываю строку из Delphi, то в Delphi же её спокойно распаковываю. Если я из Delphi пытаюсь распаковать строку, которая была обработана в Lazarus, то Base64DecodeStr - возвращает значение отличное от Lazarus, соответственно uncompress её не хавает. А если я делаю Base64DecodeStr(AnsiString(copy(s,2,ii-1))) - то на выходе я получаю тот же результат, что и в Lazarus, но uncompress всё так же отказывается распаковывать то что получается. Ну а моя задача собственно распаковать из Delphi, то что запаковано в Lazarus.
Код: Выделить всё
var
i,len : integer;
Ptr,Start : Pointer;
Destlen : Longword;
procedure WriteInteger(int : integer);
begin
PLongInt(Ptr)^ := int;
Inc(ptr,sizeof(int));
end;
procedure WriteBool(bool : boolean);
begin;
PBoolean(Ptr)^ := bool;
inc(ptr,sizeof(boolean));
end;
begin
result := '';
if Count < 1 then
exit;
len := Count * TMDTMPointSize + SizeOf(Integer);
Start:= GetMem(len);
Ptr := Start;
WriteInteger(FLen);
for i := 0 to FLen-1 do
WriteInteger(FPoints[i].x);
for i := 0 to FLen-1 do
WriteInteger(FPoints[i].y);
for i := 0 to FLen-1 do
WriteInteger(FPoints[i].c);
for i := 0 to FLen-1 do
WriteInteger(FPoints[i].t);
for i := 0 to FLen-1 do
WriteInteger(FPoints[i].asz);
for i := 0 to FLen-1 do
WriteBool(FPoints[i].bp);
Destlen :=BufferLen;
if compress(BufferString,destlen,pchar(start),len) = Z_OK then
begin
setlength(result,Destlen + SizeOf(Integer));
PInteger(@result[1])^ := len;
Move(bufferstring[0],result[1 + sizeof(integer)],Destlen);
Result := 'm' + Base64EncodeStr(result);
end;
Freemem(start,len);
end;
Соответственно на выходе я получаю строку вида:
Код: Выделить всё
mwQAAAHic42RgYOACYk4oDQLCQCwIxExAzAxlc0HFGZDUCkAxTN3CpSuBJCMBjLAHFyBkAiOyYgBXqALAЗатем уже из Delphi начинаю её разбирать:
Код: Выделить всё
var
Source : String;
DestLen : longword;
i,ii,c,size : integer;
DPoints : TMDTMPointArray;
Ptr : pbytearray;
function ReadInteger : integer;
begin
Result := PInteger(ptr)^;
inc(ptr,sizeof(integer));
end;
function ReadBoolean : boolean;
begin
result := PBoolean(ptr)^;
inc(ptr,sizeof(boolean));
end;
begin
Result := false;
ii := Length(S);
if (ii = 0) then
exit;
if S[1] = 'm' then
begin
if ii < 9 then
raise Exception.CreateFMT('Invalid DTM-String passed to StringToDTM: %s',[s]);
Source := Base64DecodeStr(copy(s,2,ii-1));
Move(Source[1], i,4);
if i < 1 then
raise Exception.CreateFMT('Invalid DTM-String passed to StringToDTM: %s',[s]);
DestLen := BufferLen;
ptr := @Source[1 + sizeof(longint)];
//ZDecompress(Pointer(BufferString),DestLen,ptr,);
if uncompress(Pbyte(BufferString),DestLen,PByte(ptr),length(source)-sizeof(integer)) = Z_OK then
begin
ptr := pbytearray(BufferString);
Self.Count:= ReadInteger;
ii := Self.Count;
if (Self.Count * TMDTMPointSize) <> (Destlen - SizeOf(integer)) then
raise Exception.CreateFMT('Invalid DTM-String passed to StringToDTM: %s',[s]);
self.SetPointCount(ii);
DPoints := Self.FPoints;
for i := 0 to ii-1 do
DPoints[i].x := ReadInteger;
for i := 0 to ii-1 do
DPoints[i].y := ReadInteger;
for i := 0 to ii-1 do
DPoints[i].c := ReadInteger;
for i := 0 to ii-1 do
DPoints[i].t := ReadInteger;
for i := 0 to ii-1 do
DPoints[i].asz := ReadInteger;
for i := 0 to ii-1 do
DPoints[i].bp := ReadBoolean;
Result := true;
end;
endФункция Base64DecodeStr - из модуля DCPCrypt64.pas; если я запаковываю строку из Delphi, то в Delphi же её спокойно распаковываю. Если я из Delphi пытаюсь распаковать строку, которая была обработана в Lazarus, то Base64DecodeStr - возвращает значение отличное от Lazarus, соответственно uncompress её не хавает. А если я делаю Base64DecodeStr(AnsiString(copy(s,2,ii-1))) - то на выходе я получаю тот же результат, что и в Lazarus, но uncompress всё так же отказывается распаковывать то что получается. Ну а моя задача собственно распаковать из Delphi, то что запаковано в Lazarus.
Заметите тип String на тип AnsiString при объявлении переменных, как Вам уже несколько раз говорилось.
Затупил-) Заменил-)) Заработало-))) Спасибо-)))))
