You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用mmap()读取时ntohl()返回0的技术求助

为什么用ntohl()读取.img文件同一位置时返回0,而ntohs()正常?

嘿,这个问题我之前帮朋友排查过类似的情况,咱们一步步拆解根源,找到解决办法~

首先得明确ntohs()和ntohl()的核心区别:前者是把16位网络字节序(大端)转成主机字节序,后者处理的是32位。你说同一位置调用两个函数结果天差地别,大概率是以下几个原因之一:

1. 数据长度不匹配,读取了无效的额外字节

如果文件里这个位置本来就只有16位的有效数据,那用ntohl()读取32位时,会把后面紧跟的16位(可能是文件填充的0)一起读进来。比如原16位数据是0x1234(大端),后面16位是0x0000,那读取的32位数据就是0x00001234,经过ntohl()转换后(假设你是小端主机),会变成0x34120000——但如果你误以为这个值是0,可能是输出时只看了高32位?不对,更可能是下面的问题。

2. 结构体类型不匹配+内存对齐坑

看你代码里定义了blockInfo结构体,用了long类型——这可是个大坑!long的长度在不同平台上不一样:32位系统是4字节,64位系统是8字节。而且编译器会给结构体自动添加对齐填充字节,导致结构体的内存布局和文件里的二进制结构完全对不上。

举个典型的例子:

  • 文件里blockSize是32位(4字节)的大端数据0x12345678
  • 你的结构体里blockSize是long(64位),在64位小端系统上,读取时会把文件里的4个有效字节+后面4个0字节拼成一个64位值:0x7856341200000000
  • 你用ntohl()处理这个值时,ntohl()只接受uint32_t类型,会自动截断高32位,结果就变成了0x00000000——这就是你看到的返回0!
  • 而用ntohs()读取前16位时,刚好命中有效数据,所以能正常返回。

3. 指针强制转换的对齐问题

如果你的映射指针是char*或uint8_t*,直接强制转成uint32_t*时,可能会碰到内存对齐错误——有些CPU不允许非对齐的4字节访问,会返回错误值(比如0)。而uint16_t*的对齐要求更低,所以能正常读取。


解决办法

针对这些问题,给你几个具体的修复步骤:

① 改用固定宽度的整数类型

把结构体里的long换成<cstdint>里的固定宽度类型,比如uint32_t(4字节)、uint16_t(2字节),这样不管什么平台,类型长度都是确定的:

#include <cstdint>

struct blockInfo {
    uint32_t blockSize = 0;
    uint32_t blockCount = 0;
    // 其他字段...
} __attribute__((packed)); // GCC/Clang下禁用自动对齐填充,MSVC用#pragma pack(push,1)

加上__attribute__((packed))是为了让结构体的内存布局和文件完全一致,避免编译器自动加填充字节。

② 安全读取数据,避免对齐问题

别直接强制转换指针,用memcpy把字节复制到对应的变量里,再做字节序转换:

// 假设img_ptr是mmap返回的uint8_t*指针
blockInfo info;

// 读取blockSize
memcpy(&info.blockSize, img_ptr, sizeof(info.blockSize));
info.blockSize = ntohl(info.blockSize); // 仅当文件是大端字节序时用

// 读取blockCount(偏移blockSize的长度)
memcpy(&info.blockCount, img_ptr + sizeof(info.blockSize), sizeof(info.blockCount));
info.blockCount = ntohl(info.blockCount);

③ 先验证原始字节

如果还是有问题,先打印出读取位置的原始字节,确认数据是否符合预期:

// 打印前4字节的原始十六进制值
printf("Raw bytes at target position: 0x%02X%02X%02X%02X\n",
       img_ptr[0], img_ptr[1], img_ptr[2], img_ptr[3]);

这样就能一眼看出文件里的实际数据是不是你想要的,排除字节序或位置偏移的问题。

内容的提问来源于stack exchange,提问作者JoryAnderson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:27:39