Упражнение: что не так в этом коде? В предположении, что все параметры указаны верно. Функция, если что, возвращает
Z_OK
:
function InitDeflate(const ACompressionLevel: Byte): TZStreamRec; var Code: Integer; begin FillChar(Result, SizeOf(Result), 0); Code := System.ZLib.deflateInit_(Result, ACompressionLevel, zlib_version, SizeOf(TZStreamRec)); // ... далее идёт анализ Code // в данном случае Code = Z_OK end;
Бонус-упражнение: найдите описание этого поведения в документации к ZLib.
Может быть, не финализируется Result перед выполнением FillChar?
ОтветитьУдалитьZLib - это C библиотека, она в проект подключается через уже скомпилированные .obj. Соответственно, C понятия не имеет про автофинализируемые типы Delphi. Следовательно, автофинализируемых типов в TZStreamRec нет.
УдалитьМожет, оригинальная библиотека полагает TZStreamRec неперемещаемым (некопируемым)? Тогда result может указывать на временную переменную вместо настоящей цели присваивания, и если ZLib зачем-нибудь сохраняет указатель на z_streamp (TZStreamRec), он сломается. Пример: если есть функция f(var a: SomeType), то код a := f(a) будет выполнен как temp := f(a); a := temp, чтобы когда функция начнёт писать что-то в результат, это не вызвало неожиданных изменений ссылочного параметра a.
ОтветитьУдалитьГорячо.
Удалитьче-то в конце многовато скобок.
ОтветитьУдалитьОдна лишняя?
Ага, спасибо, подправил. Опечатка.
Удалитьв описании этой функци указано всего 2 параметра, см https://zlib.net/manual.html
ОтветитьУдалитьdeflateInit - это макрос, а реальная функция там как раз deflateInit_: https://refspecs.linuxbase.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/zlib-deflateinit.html
Удалить