Манипуляции с порядком байтов - есть ли для этого библиотека C? - PullRequest
9 голосов
/ 03 апреля 2010

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

Единственные вещи, которые я могу найти, - это вызовы сокетов, такие как htons (), но для них требуются разные файлы #include на каждой платформе, и некоторый код GPL , такой как , однако этот конкретный файл, хотя и является всеобъемлющим, кажется упустите некоторые из высокопроизводительных функций, предоставляемых некоторыми компиляторами.

Итак, кто-нибудь знает библиотеку (в идеале просто файл .h), которая хорошо протестирована и предоставляет стандартный набор функций для работы с порядком байтов во многих компиляторах и платформах?

Ответы [ 4 ]

2 голосов
/ 03 апреля 2010

Проще всего не писать код, зависящий от порядка байтов. Вы никогда не должны заботиться о том, какова последовательность системы, на которой вы работаете; единственное, что должно иметь значение, - это то, что является обязательным порядком байтов для любых внешних данных, которые вы читаете или пишете. Вам не следует спрашивать о преобразованиях между значениями с прямым и прямым порядком байтов, а о преобразованиях с прямым порядком байтов в порядковый номер хоста, и вы можете написать этот код в независимом от порядков, который (почти) полностью переносим: 1001 *

Например: предположим, что вы читаете 32-разрядное целое число с прямым порядком байтов из потока файлов:

/*
 * Note that callers should check feof(fp) afterward to verify that
 * there was enough data to read.
 */
uint32_t GetBE32(FILE* fp)
{
    uint32_t result;
    result  = fgetc(fp) << 24;
    result |= fgetc(fp) << 16;
    result |= fgetc(fp) <<  8;
    result |= fgetc(fp);
    return result;
}

uint32_t GetLE32(FILE* fp)
{
    uint32_t result;
    result  = fgetc(fp);
    result |= fgetc(fp) <<  8;
    result |= fgetc(fp) << 16;
    result |= fgetc(fp) << 24;
    return result;
}

(я говорю «(почти) полностью переносимый», потому что он предполагает, что имеется 8 бит на байт. Но если вы работаете в системе, где это не так, у вас, вероятно, будут большие проблемы, когда работа с внешними данными.)

2 голосов
/ 03 апреля 2010

Был целый ряд предложений для класса Boost (по крайней мере для C ++), чтобы сделать именно это за последнее десятилетие, но, к сожалению, ни одно из них не было реализовано.

Я не знаю лучшего обобщенного решения, чем набор функций htons ().

1 голос
/ 19 января 2018

За что стоит ...

Как и OP, мне часто нужны подпрограммы с поддержкой порядка байтов для перетасовки данных между различными машинами и протоколами. (В моем случае они нужны мне для встроенных процессоров, а не для большого железа.)

После нескольких итераций я разместил библиотеку с порядком байтов , написанную на чистом C, для Github. Чего не хватает в документации, так это для полного комплексного тестирования.

https://github.com/rdpoor/endian

endian Основным отличием большинства библиотек упорядочивания байтов является то, что он не предполагает функции чтения или записи по байтам за раз, а скорее работает непосредственно на буферах памяти void *. Это дает компилятору свободу оптимизировать то, что он может, и в случае, если желаемое упорядочение байтов совпадает с хост-машиной, он вообще закорачивает перемешивание байтов.

1 голос
/ 20 декабря 2013

В Linux есть <endian.h>

http://man7.org/linux/man-pages/man3/htole32.3.html

Мне было бы интересно узнать, поддерживают ли его и другие операционные системы.

...