如何在Objective-C中反转NSInteger或NSUInteger的字节顺序

6
这是一个关于IT技术的问题,与此帖子有些类似,但提出了不同的问题,所以我觉得应该在单独的主题中提问。
我已经从文件中读取了四个连续的字节,并希望将它们存储为位数组(直到后面实际的int值才有意义)。当我打印我的int中的内容时,我注意到它似乎是以相反的顺序(小端)存储的。
请问是否有好的方法来颠倒字节的顺序?然后一旦颠倒,如何挑选跨越两个字节的连续位并转换回int?
unsigned char data[] = { 0x00, 0x02, 0x45, 0x28 };
NSInteger intData = *((NSInteger *)data);

NSLog(@"data:%08x", intData); // data:28450200
1个回答

16

Cocoa(准确来说是Foundation框架)有函数可以交换字节的大小端: NSSwapIntNSSwapShortNSSwapLongNSSwapLongLong。它们无论如何都会交换字节 - 它们将小端整数转换为大端整数,反之亦然。

如果您知道您具有哪种格式,则有其他函数可将其交换到本机字节序: NSSwapLittleIntToHostNSSwapBigIntToHost。也有反向功能,它们将从本机格式交换到小端或大端格式:NSSwapHostIntToLittleNSSwapHostIntToBig。这些功能也适用于其他整数类型和浮点类型。它们的作用是在必要时对值调用基本交换函数。因此,NSSwapLittleIntToHost不做任何操作,而NSSwapBigIntToHost在小端机器上返回NSSwapInt的结果。

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

您也不应将您的字节数组强制转换为整数指针并对其进行解引用。最好使用位移操作组装整数。如果NSInteger为32位宽,则您的代码将仅有效。如果它是64位,则您的数字将是垃圾,或者您的程序甚至可能崩溃。但即使您使用的是始终为32位宽的整数类型(例如C99 <stdint.h>头文件中的int32_t),这也可能不能按预期工作。


谢谢,我已经找了很久,没有找到NSSwapBigIntToHost。最终我按照你的建议进行了一些低位操作。在我的代码中,我做了一个假设,即我的整数将是32位的。我最终创建了一个unsigned char tref = (unsigned char)&temp;,然后循环交换字节,最后将tref强制转换为整数。虽然不太美观,但只要我使用32位就能正常工作。 - Scott

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接