Упражнение: что не так в этом коде? В предположении, что все параметры указаны верно. Функция, если что, возвращает
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 года назад, и как раз в EurekaLog (модуль EPNG.pas)!
УдалитьНо только в 64-битном Delphi. 32-битный компилятор нормально работал, не выделял дополнительную память, а Result трактовал как var-параметр.
Почему-то 64-битный компилятор делал именно так, как Вы пишете, создавал временную переменную. Почему так — я не помню уже, 2 года прошло. Видимо, из-за каких-то особенностей вложенных функций в Win64.
че-то в конце многовато скобок.
ОтветитьУдалитьОдна лишняя?
Ага, спасибо, подправил. Опечатка.
Удалитьв описании этой функци указано всего 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
Удалить