转换字节序时出现问题
我正在按照本教程在 C++ 中使用 OpenAL: http://enigma-dev .org/forums/index.php?topic=730.0
正如您在教程中看到的,他们留下了一些未实现的方法,并且我在实现 file_read_int32_le(char*, FILE*) 和 file_read_int16_le(char*, FILE*)。显然它应该做的是从文件中加载 4 个字节(或者在 int16 的情况下加载 2 个字节,我猜......),将其从小端字节序转换为大端字节序,然后将其作为无符号整数返回。代码如下:
static unsigned int file_read_int32_le(char* buffer, FILE* file) {
size_t bytesRead = fread(buffer, 1, 4, file);
printf("%x\n",(unsigned int)*buffer);
unsigned int* newBuffer = (unsigned int*)malloc(4);
*newBuffer = ((*buffer << 24) & 0xFF000000U) | ((*buffer << 8) & 0x00FF0000U) | ((*buffer >> 8) & 0x0000FF00U) | ((*buffer >> 24) & 0x000000FFU);
printf("%x\n", *newBuffer);
return (unsigned int)*newBuffer;
}
调试时(在 XCode 中)它说 *buffer 的十六进制值为 0x72,这只是一个字节。当我使用 malloc(4) 创建 newBuffer 时,我得到一个 4 字节缓冲区(*newBuffer 类似于 0xC0000003),在操作之后,它变成 0x72000000。我假设我正在寻找的结果是 0x00000027 (编辑:实际上是 0x00000072),但是我将如何实现这一点?这与 char* 缓冲区和 unsigned int* newBuffer 之间的转换有关吗?
I'm following this tutorial for using OpenAL in C++: http://enigma-dev.org/forums/index.php?topic=730.0
As you can see in the tutorial, they leave a few methods unimplemented, and I am having trouble implementing file_read_int32_le(char*, FILE*) and file_read_int16_le(char*, FILE*). Apparently what it should do is load 4 bytes from the file (or 2 in the case of int16 I guess..), convert it from little-endian to big endian and then return it as an unsigned integer. Here's the code:
static unsigned int file_read_int32_le(char* buffer, FILE* file) {
size_t bytesRead = fread(buffer, 1, 4, file);
printf("%x\n",(unsigned int)*buffer);
unsigned int* newBuffer = (unsigned int*)malloc(4);
*newBuffer = ((*buffer << 24) & 0xFF000000U) | ((*buffer << 8) & 0x00FF0000U) | ((*buffer >> 8) & 0x0000FF00U) | ((*buffer >> 24) & 0x000000FFU);
printf("%x\n", *newBuffer);
return (unsigned int)*newBuffer;
}
When debugging (in XCode) it says that the hexadecimal value of *buffer is 0x72, which is only one byte. When I create newBuffer using malloc(4), I get a 4-byte buffer (*newBuffer is something like 0xC0000003) which then, after the operations, becomes 0x72000000. I assume the result I'm looking for is 0x00000027 (edit: actually 0x00000072), but how would I achieve this? Is it something to do with converting between the char* buffer and the unsigned int* newBuffer?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,*buffer 将在 Xcode 的调试器中读取为 0x72,因为 buffer 是指向字符的指针。
如果buffer指向的内存块中的前四个字节是(十六进制)72 00 00 00,那么返回值应该是0x00000072,而不是0x00000027。字节应该被交换,但组成每个字节的两个“nybbles”不应该被交换。
这段代码泄漏了您分配的内存,无论如何您都不需要在这里分配内存。
您的字节交换在 PowerPC 或 68K Mac 上是正确的,但在 Intel Mac 或基于 ARM 的 iOS 上则不正确。在这些平台上,您不必进行任何字节交换,因为它们本身就是小端字节序。
Core Foundation 提供了一种更轻松地完成这一切的方法:
Yes, *buffer will read in Xcode's debugger as 0x72, because buffer is a pointer to a char.
If the first four bytes in the memory block pointed to by buffer are (hex) 72 00 00 00, then the return value should be 0x00000072, not 0x00000027. The bytes should get swapped, but not the two "nybbles" that make up each byte.
This code leaks the memory you malloc'd, and you don't need to malloc here anyway.
Your byte-swapping is correct on a PowerPC or 68K Mac, but not on an Intel Mac or ARM-based iOS. On those platforms, you don't have to do any byte-swapping because they're natively little-endian.
Core Foundation provides a way to do this all much more easily:
有一系列名为“htons/htonl/hton”的函数,其唯一目的是将“主机”字节顺序转换为“网络”字节顺序。
http://beej.us/guide/bgnet/output/html/multipage /htonsman.html
每个函数都有一个执行相反操作的倒数。
现在,这些函数不一定对您有帮助,因为它们本质上是从主机特定的字节顺序转换的,所以请使用这个答案作为起点来查找您需要的内容。一般来说,代码永远不应该假设它所在的架构。
英特尔==“小端”。
网络==“大端”。
希望这能让您走上正确的道路。
there's a whole range of functions called "htons/htonl/hton" whose sole purpose in life is to convert from "host" to "network" byte order.
http://beej.us/guide/bgnet/output/html/multipage/htonsman.html
Each function has a reciprocal that does the opposite.
Now, these functions won't help you necessarily because they intrinsically convert from your hosts specific byte order, so please just use this answer as a starting point to find what you need. Generally code should never make assumptions about what architecture it's on.
Intel == "Little Endian".
Network == "Big Endian".
Hope this starts you out on the right track.
我将以下内容用于整数类型。在某些平台上,对于非整数类型来说并不安全。
因此,将其放入文件读取器中(为什么要传递缓冲区,因为它看起来可能是临时的)
I've used the following for integral types. On some platforms, it's not safe for non-integral types.
So, to put that in your file reader (why are you passing the buffer in, since it appears that it could be a temporary)