Отличия строк Delphi и Lazarus.

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Отличия строк Delphi и Lazarus.

Сообщение CynicRus » 30.05.2013 17:54:13

Привествую уважаемых форумчан. Имеется 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, не помогло).
CynicRus
постоялец
 
Сообщения: 106
Зарегистрирован: 28.06.2012 14:31:11

Re: Отличия строк Delphi и Lazarus.

Сообщение alexey38 » 30.05.2013 20:00:46

В Delphi XE 3 есть UnicodeString = String и есть AnsiString.
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

Re: Отличия строк Delphi и Lazarus.

Сообщение CynicRus » 30.05.2013 20:26:42

Я знаю, цимес в том что и в том и в другом случае используется String. Вот я и не пойму, где я туплю.

Добавлено спустя 1 час 4 минуты 33 секунды:
Вообщем косяк был в юните Декодирования Base64. Ему оказывается надо было кормить Ansi?String.

Добавлено спустя 38 минут 6 секунд:
Но хоть теперь результаты строк и одинаковы, что в дельфи, что в лазаре - но Дельфя отчаянно не хочет распаковывать то что ей подали на вход. И тут я уже теряюсь в догадках:)
CynicRus
постоялец
 
Сообщения: 106
Зарегистрирован: 28.06.2012 14:31:11

Re: Отличия строк Delphi и Lazarus.

Сообщение Снег Север » 31.05.2013 06:58:48

В Делфи, начиная с 2009 и выше sting- это WideString!
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3053
Зарегистрирован: 27.11.2007 16:14:47

Re: Отличия строк Delphi и Lazarus.

Сообщение Light13 » 31.05.2013 07:09:00

Приведите примеры кода - дело пойдет быстрее.

В Лазаре строки строятся на базе мультибайтных символов (utf8), в дельфи, начиная с 2009, на базе двухбайтных (unicode).

Откажитесь от строк и работайте с блоками памяти - будет проще.

Также не забывайте про кодировку - в дельфи компилятор автоматически вставляет преобразования, иногда не совсем прозрачно.
Аватара пользователя
Light13
постоялец
 
Сообщения: 127
Зарегистрирован: 17.07.2009 07:50:10
Откуда: Челябинск

Re: Отличия строк Delphi и Lazarus.

Сообщение alexey38 » 31.05.2013 07:24:18

Снег Север писал(а):В Делфи, начиная с 2009 и выше sting- это WideString!

Немного не так. В Дельфи начиная с 2009:
String = UnicodeString;
WideString <> UnicodeString, хотя оба типа для уникода.
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

Re: Отличия строк Delphi и Lazarus.

Сообщение CynicRus » 31.05.2013 09:24:49

И так, в связи с тем что пока мои телодвижения не принесли результатов - прилагаю образцы кода. В лазарусе структура, а точнее массив структур пишется следующим образом:
Код: Выделить всё
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.
CynicRus
постоялец
 
Сообщения: 106
Зарегистрирован: 28.06.2012 14:31:11

Re: Отличия строк Delphi и Lazarus.

Сообщение alexey38 » 31.05.2013 12:14:15

Заметите тип String на тип AnsiString при объявлении переменных, как Вам уже несколько раз говорилось.
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

Re: Отличия строк Delphi и Lazarus.

Сообщение CynicRus » 31.05.2013 13:59:12

Затупил-) Заменил-)) Заработало-))) Спасибо-)))))
CynicRus
постоялец
 
Сообщения: 106
Зарегистрирован: 28.06.2012 14:31:11


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 234

Рейтинг@Mail.ru