Как я могу изменить порядок байтов NSInteger или NSUInteger в target-c - PullRequest
6 голосов
/ 30 сентября 2010

Это что-то вроде продолжения этой публикации , но с другим вопросом, поэтому я решил задать его в отдельной ветке.

Я нахожусь в точке, где у меня есть четыре последовательных байта в памяти, которые я прочитал из файла. Я хотел бы сохранить их как битовый массив (фактическое значение int для них не имеет значения, пока не будет). Когда я распечатываю то, что находится в моем int, я замечаю, что оно, кажется, хранится в обратном порядке (little-endian).

Есть ли у кого-нибудь хороший метод для изменения порядка следования байтов. Затем, однажды перевернув, выбрав последовательные биты, занимающие два байта, и преобразовав их обратно в целое число?

unsigned char data[] = { 0x00, 0x02, 0x45, 0x28 };
NSInteger intData = *((NSInteger *)data);

NSLog(@"data:%08x", intData); // data:28450200

1 Ответ

15 голосов
/ 30 сентября 2010

Какао (или, если быть точным, базовая структура) имеет функции для замены байтов байтов: NSSwapInt, NSSwapShort, NSSwapLong и NSSwapLongLong.Они обмениваются вокруг байтов, независимо от того, что - они делают целые числа с прямым порядком байтов из целых чисел с прямым порядком байтов и наоборот.

Если вы знаете, какой у вас формат, есть другие функции, которые меняют его на собственный порядок байтов: NSSwapLittleIntToHost и NSSwapBigIntToHost.Есть также обратные функции, которые меняют местный формат на формат с прямым или обратным порядком байтов: NSSwapHostIntToLittle и NSSwapHostIntToBig.Они также доступны для других целочисленных типов и типов с плавающей точкой.То, что они делают, они при необходимости вызывают примитивные функции подстановки значений.Так что NSSwapLittleIntToHost ничего не делает, в то время как NSSwapBigIntToHost возвращает результат NSSwapInt на машине с прямым порядком байтов.

Обратите внимание, что они принимают параметры целочисленных типов компиляторов, а не типа NSInteger.Таким образом, в зависимости от того, генерируете ли вы 32-битный или 64-битный код, вы должны использовать разные функции, если вы используете NSInteger.

Вы также не должны приводить свой байтовый массив к целочисленному указателю и разыменовывать его.Было бы лучше собрать целое число, используя операции сдвига битов.Ваш код будет работать, только если NSInteger имеет ширину 32 бита.Если он 64-битный, то ваш номер будет мусором, иначе ваша программа может даже зависнуть.Но даже если вы используете целочисленный тип, который всегда имеет ширину 32 бита (например, int32_t из заголовка C99 <stdint.h>), это может работать не так, как ожидается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...