Какова цель различных типов, добавленных zlib, и как я могу их использовать?

В настоящее время я пытаюсь с целью изучения базового использования zlib создать небольшую утилиту для сжатия и распаковки файлов на С++. Я использую функции compress2 и uncompress, предоставляемые zlib, чтобы облегчить это. Однако обе эти функции принимают различные типы, кажущиеся специфичными для zlib (Bytef, uLongf и т. д.), без каких-либо автоматических преобразований между ними и типами C++ (точнее, указатели на каждый из этих типов). Это делает простой код для взаимодействия с zlib более сложным, если только я не напишу все свое приложение, основанное на типах zlib.

Мой вопрос состоит из 3 частей:

  • Какова цель этих типов в отличие от встроенных типов, таких как unsigned long, которые я использую в своем собственном коде ввода-вывода файлов для представления длины файлов?
  • Как правильно использовать эти типы? Могу ли я переинтерпретировать приведение моих указателей char к данным для (де) сжатия до указателей Bytef без изменения длины данных из длины моего массива символов? Поскольку char — это один байт, а имя Bytef предполагает, что оно имеет одинаковую длину, я думаю, что могу, но хочу убедиться. Могу ли я просто назначить unsigned long (или другой интегральный тип, отличный от zlib) для uLongf и других, казалось бы, интегральных типов zlib?
  • Где официальная документация zlib по этим типам?

Я просмотрел руководство по zlib и полностью прочитал разделы, которые могут показаться важными, вместе с клавишей Ctrl +f вспомогательный поиск, безрезультатно. Мой поисковик тоже не знает ответа.


person john01dav    schedule 14.07.2018    source источник
comment
Вы говорите, что нет автоматического преобразования в типы C++, но, насколько я помню, например, Bytef — это псевдоним типа для unsigned char. Уверены ли вы?   -  person Lightness Races in Orbit    schedule 14.07.2018
comment
(Я ожидаю, что псевдонимы существуют для того, чтобы обеспечить общий набор имен типов для языковых привязок.)   -  person Lightness Races in Orbit    schedule 14.07.2018
comment
По общему признанию, руководство кажется слабым в этом отношении, но это должно быть ясно из фактических заголовков.   -  person Lightness Races in Orbit    schedule 14.07.2018
comment
У меня нет проблем с использованием стандартных типов с zlib. Это просто определения типов в zconf.h.   -  person Retired Ninja    schedule 14.07.2018
comment
Вы упоминаете unsigned long - это 32 или 64 бита в зависимости от того, какой компилятор вы используете.   -  person Sid S    schedule 14.07.2018
comment
Правильный тип размера файла – off_t, но даже в этом случае вам все равно придется использовать #define _FILE_OFFSET_BITS 64 на 32-разрядных платформах.   -  person o11c    schedule 14.07.2018
comment
Все типы zlib кажутся определениями типов для различных встроенных типов, но я использую немного другие типы, чем те, которые предпочитает zlib (т. е. char*, а не unsigned char*), что делает указатели, используемые функциями zlib, несовместимыми с моими собственными. Заголовок zconf.h говорит мне, для чего они определены, но typedef предполагает, что я должен использовать их как-то иначе, чем встроенные типы (иначе, зачем делать их похожими на отдельные типы?). Однако комментарии здесь, похоже, говорят об обратном. Есть ли официальные документы, подтверждающие это?   -  person john01dav    schedule 14.07.2018
comment
f обозначает дальний указатель из 16-битной сегментированной эпохи, которая имела разный синтаксис в разных компиляторах, поэтому абстракция. В настоящее время он определяется как обычный указатель.   -  person o11c    schedule 14.07.2018
comment
Нередко библиотеки используют какую-то конфигурацию, чтобы быть переносимыми в системах, где типы по своей сути различны или должны быть указаны по-разному. По моему опыту, это редко документируется, поскольку обычно это не проблема. Возможно, вы читаете в этом сложность, которой там нет.   -  person Retired Ninja    schedule 14.07.2018
comment
Обычно реализуется тонкий связующий слой, который адаптирует данные приложения к контракту библиотеки. Хитрость заключается в том, чтобы сделать это эффективно. Преобразование из неподписанного в подписанный char будет выполняться в клее, поэтому в противном случае вы можете его игнорировать. Char против unsigned char — интересный пример. Почти на всех архитектурах просто будет работать приведение массива одного массива к другому, при этом компилятор не генерирует код. Но C++ не гарантирует этого, поэтому для некоторых может потребоваться специальная обработка. Слой клея закрепляет этот беспорядок.   -  person Gene    schedule 14.07.2018


Ответы (1)


  • Для переносимости длина ваших файлов должна использовать off_t, а не unsigned long. В некоторых системах это разные размеры, причем off_t длиннее.
  • Да, вы можете просто использовать между Bytef и char. (Bytef на самом деле unsigned char, но преобразование не требуется.) uLong это просто unsigned long. (См. zconf.h.)
  • Документация zlib — zlib.h, где эти типы вызываются как параметры функций. Вы можете использовать zlibCompileFlags() для определения количества битов в каждом типе. (См. zlib.h.)
person Mark Adler    schedule 14.07.2018