如何在objective-c中反转NSInteger或NSUInteger的字节顺序

时间:2010-09-30 13:17:23

标签: objective-c bytearray byte endianness nsinteger

这是对this posting的一些跟进,但有一个不同的问题,所以我觉得我应该在一个单独的帖子中提问。

我正处于从内存中读取四个连续字节的位置。我想将它们存储为一个位数组(它们的实际int值直到后来都无关紧要)。当我打印出我的int中的内容时,我注意到它似乎以相反的顺序存储(小端)。

有没有人有一个很好的方法来反转字节的顺序。然后反转,挑出跨越两个字节的连续位并转换回int?

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

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

1 个答案:

答案 0 :(得分:15)

Cocoa(或者确切地说是Foundation框架)具有交换字节字节序的功能:NSSwapIntNSSwapShortNSSwapLongNSSwapLongLong。无论如何,它们都会在字节周围交换 - 它们从小端整数中产生大端整数,反之亦然。

如果您知道自己的格式,则可以使用其他函数将其交换为本机字节序:NSSwapLittleIntToHostNSSwapBigIntToHost。还有一些反向函数可以从原生格式转换为小端或大端格式:NSSwapHostIntToLittleNSSwapHostIntToBig。这些也可用于其他整数类型和浮点类型。他们所做的是在必要时调用值上的原始交换函数。因此NSSwapLittleIntToHostNSSwapBigIntToHost在小端机器上返回NSSwapInt的结果时不会执行任何操作。

请注意,这些参数包含编译器整数类型而不是NSInteger类型。因此,如果您使用的是NSInteger,则必须使用不同的函数,因此您需要生成32位或64位代码。

您也不应该将字节数组转换为整数指针并取消引用它。使用位移操作组装整数会更好。只有当NSInteger为32位宽时,您的代码才有效。如果它是64位,那么你的号码将是垃圾或你的程序甚至可能崩溃。但即使您使用的是一个总长度为32位的整数类型(例如,来自C99 int32_t标头的<stdint.h>),这可能无法正常工作。