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

发布于 2024-09-25 12:53:29 字数 484 浏览 2 评论 0原文

这是这篇文章的后续内容< /a> 但有一个不同的问题,所以我觉得我应该在一个单独的线程中提问。

我现在已经从文件中读入了内存中的四个连续字节。我想将它们存储为位数组(它们的实际 int 值稍后才重要)。当我打印出 int 中的内容时,我注意到它似乎以相反的顺序存储(小端)。

有谁有反转字节顺序的好方法。然后一旦反转,选出跨越两个字节的连续位并转换回 int?

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

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

This is a somewhat of a follow up to this posting but with a different question so I felt I should ask in a separate thread.

I am at the point where I have four consecutive bytes in memory that I have read in from a file. I'd like to store these as a bit array (the actual int value of them does not matter until later). When I print out what is in my int, I notice that it seems to be stored in reverse order (little endian).

Does anyone have a good method for reversing the order of the bytes. Then once reversed, picking out consecutive bits spanning two bytes and converting back to an int?

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

勿忘初心 2024-10-02 12:53:29

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

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

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

您也不应该将字节数组转换为整数指针并取消引用它。最好使用位移操作来组装整数。仅当 NSInteger 为 32 位宽时,您的代码才有效。如果是 64 位,那么你的号码将是垃圾,或者你的程序甚至可能崩溃。但即使您使用始终为 32 位宽的整数类型(例如,来自 C99 标头的 int32_t),这也可能无法按预期工作。

Cocoa (or to be exact the Foundation framework) has functions to swap the endianness of bytes: NSSwapInt, NSSwapShort, NSSwapLong, and NSSwapLongLong. These swap around the bytes no matter what - they make big-endian integers from small-endian integers and vice versa.

If you know which format you have there are other functions that swap it to the native endianness: NSSwapLittleIntToHost and NSSwapBigIntToHost. There are also the reverse functions which swap from the native format to little or big endian format: NSSwapHostIntToLittle and NSSwapHostIntToBig. Those are available for the other integer types and floating point types as well. What they do is they call the primitive swap functions on the values if necessary. So NSSwapLittleIntToHost doesn’t do anything while NSSwapBigIntToHost returns the result of NSSwapInt on a little endian machine.

Note that these take parameters of the compilers integer types and not the NSInteger type. So depending on wether you’re generating 32bit or 64bit code you have to use different functions if you are using NSInteger.

You also should not cast your byte array to an integer pointer and dereference that. It would be better to assemble the integer using bit shift operations. Your code will only work if NSInteger is 32 bit wide. If it is 64 bit then your number will be garbage or your program might even crash. But even if you are using an integer type that is always 32 bit wide (int32_t from the C99 <stdint.h> header for example) this might not work as expected.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文