Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.05.2014, 16:10   #1
STRELOK-2007
Форумчанин
 
Регистрация: 06.08.2009
Сообщений: 144
Вопрос LzmaCompress

Приветствую!

Скачал LZMA SDK с оффсайта, скопилировал проект с помощью VS2013. На выходе получил LZMA.dll. Сразу переименовал ее в LZMA_x32.dll, скомпилировал 64-разрядную версию и переименовал ее в LZMA_x64.dll.

Далее.
Вроде как правильно перевел определение функции LZMAEncode (для начала)

C++

Код:
MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
  unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
  int level,      /* 0 <= level <= 9, default = 5 */
  unsigned dictSize,  /* default = (1 << 24) */
  int lc,        /* 0 <= lc <= 8, default = 3  */
  int lp,        /* 0 <= lp <= 4, default = 0  */
  int pb,        /* 0 <= pb <= 4, default = 2  */
  int fb,        /* 5 <= fb <= 273, default = 32 */
  int numThreads /* 1 or 2, default = 2 */
  );
Delphi

Код:
 TLZMACompressFunc = function(
  dest: PByte;
  destLen: PSIZE_T;
  const src: PByte;
  srcLen: SIZE_T;
  outProps: PByte;
  outPropsSize: PSIZE_T; //* *outPropsSize must be = 5 */
  level: Integer;      //* 0 <= level <= 9, default = 5 */
  dictSize: Cardinal; //* default = (1 << 24) */
  lc: Integer;        //* 0 <= lc <= 8, default = 3  */
  lp: Integer;        //* 0 <= lp <= 4, default = 0  */
  pb: Integer;        //* 0 <= pb <= 4, default = 2  */
  fb: Integer;        //* 5 <= fb <= 273, default = 32 */
  numThreads: Integer //* 1 or 2, default = 2 */
  ): Integer; stdcall;
Правильно же?

Далее
Решил испытать код. Сперва, разумеется, почитал комментарии в LibLzma.h. Если я правильно понял, то вся соль в первых 6 параметрах функции - остальные можно указать как -1 (0 для размера словаря), чтобы использовались значения по умолчанию. Для первого теста это и требуется.

Вот как я понял назначение параметров, логически разделенных на 3 пары.
  1. Первая пара параметров - это указатель на массив байт и указатель на размер, в который запишутся сжатые данные и их размер.
  2. Вторая пара - это указатель на массив байт с исходными данными и их размер (не указатель).
  3. Третья пара - указатель на массив каких то параметров и указатель на размер.

Написал вот такой код:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
 Lib: THandle;
 LibName: WideString;

 LZMAc: TLZMACompressFunc;

 i: array of byte;
 o: array of byte;
 p: array[0..4] of byte;

 l: SIZE_T;
 ol: SIZE_T;
 pl: SIZE_T;

 str: WideString;

 res: integer;
begin
 Memo1.Lines.Clear;
 Memo1.Lines.Add(LZMA_dll) ;
 Memo1.Lines.Add(GetCurrentDir);

 LibName:=IncludeTrailingPathDelimiter(GetCurrentDir) + LZMA_dll;

 Memo1.Lines.Add(LibName);

 Lib:=LoadLibraryW(PWideChar(LibName));

 Memo1.Lines.Add('Handle: ' + IntToStr(Lib));

 @LZMAc:= GetProcAddress(Lib, LZMA_Compress);

 Memo1.Lines.Add(LZMA_Compress + '   0x' + IntToHex(NativeUINT(Pointer(@LZMAc)), SizeOF(NativeUINT) * 2));

 str:=Edit1.Text;

 l:=Length(str) * 2;

 SetLength(i, l);
  Move(str[1], i[0], l);

 res:=-1;

 //ol:=l;
 //SetLength(o, ol);

 try
   res:=LZMAc(@o[0],
              @ol,
              @i[0],
              l,
              @p[0],
              @pl,
              -1,
              0,
              -1,
              -1,
              -1,
              -1,
              -1);
 except
  on E: Exception do
   Memo1.Lines.Add('Exception: ' + E.Message) ;
 end;

 Memo1.Lines.Add(Res2String(res));
end;
Не работает!

Пробовал указывать просто, например @i.

Всегда пишет вот так:
Код:
LZMA_x32.dll
C:\Users\VIRUS\Documents\RAD Studio\Projects\Tests\LZMA\data
C:\Users\VIRUS\Documents\RAD Studio\Projects\Tests\LZMA\data\LZMA_x32.dll
Handle: 1361772544
LzmaCompress   0x512B8810
SZ_ERROR_PARAM
т.е. ошибка с параметрами. что-то указано не правильно, но что конкретно?

Заранее спасибо!
STRELOK-2007 вне форума Ответить с цитированием
Старый 01.05.2014, 16:26   #2
STRELOK-2007
Форумчанин
 
Регистрация: 06.08.2009
Сообщений: 144
По умолчанию

x64 версия выдает то-же самое

Код:
LZMA_x64.dll
C:\Users\VIRUS\Documents\RAD Studio\Projects\Tests\LZMA\data
C:\Users\VIRUS\Documents\RAD Studio\Projects\Tests\LZMA\data\LZMA_x64.dll
Handle: 140722368872448
LzmaCompress   0x00007FFC7ACF9910
SZ_ERROR_PARAM
STRELOK-2007 вне форума Ответить с цитированием
Старый 01.05.2014, 17:07   #3
eval
Подтвердите свой е-майл
 
Регистрация: 29.08.2012
Сообщений: 4,011
По умолчанию

соглашение о вызовах совпали?
eval вне форума Ответить с цитированием
Старый 01.05.2014, 17:21   #4
STRELOK-2007
Форумчанин
 
Регистрация: 06.08.2009
Сообщений: 144
По умолчанию

Цитата:
Сообщение от eval Посмотреть сообщение
соглашение о вызовах совпали?
http://floomby.ru/s2/wWvnfY

Я ведь правильно понял, что используется stdcall соглашение и int в качестве результата?
STRELOK-2007 вне форума Ответить с цитированием
Старый 01.05.2014, 17:24   #5
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Цитата:
SZ_ERROR_PARAM
Какой-то параметр передаете не верно, вот и проблема.
Человек_Борща вне форума Ответить с цитированием
Старый 01.05.2014, 17:48   #6
STRELOK-2007
Форумчанин
 
Регистрация: 06.08.2009
Сообщений: 144
По умолчанию

Цитата:
Сообщение от Человек_Борща Посмотреть сообщение
Какой-то параметр передаете не верно, вот и проблема.
Это понятно, я это и сказал в начальном сообщении) Только вот какой именно параметр?
STRELOK-2007 вне форума Ответить с цитированием
Старый 01.05.2014, 20:29   #7
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Цитата:
Только вот какой именно параметр?
Методом тыка.
Человек_Борща вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц