c - 是否有一种独立于体系结构的方法来从 C 中的值创建小端字节流?
问题描述
我试图通过创建一个 uint8_t[] 缓冲区然后发送它来在架构之间传输值。为了确保它们被正确传输,规范是在所有值进入缓冲区时将它们转换为 little-endian。
我在这里阅读了这篇文章,其中讨论了如何从一种字节序转换为另一种字节序,在这里它讨论了如何检查系统的字节序。
我很好奇是否有一种方法可以以小端顺序从 uint64 或其他值读取字节,而不管系统是大还是小?(即通过一些位操作序列)
或者是首先检查系统字节序的唯一方法,然后如果大显式转换为小?
解决方案
这实际上很简单——您只需使用转换在“本机”格式(无论是什么)和小端格式之间进行转换
/* put a 32-bit value into a buffer in little-endian order (4 bytes) */
void put32(uint8_t *buf, uint32_t val) {
buf[0] = val;
buf[1] = val >> 8;
buf[2] = val >> 16;
buf[3] = val >> 24;
}
/* get a 32-bit value from a buffer (little-endian) */
uint32_t get32(uint8_t *buf) {
return (uint32_t)buf[0] + ((uint32_t)buf[1] << 8) +
((uint32_t)buf[2] << 16) + ((uint32_t)buf[3] << 24);
}
如果将一个值放入缓冲区,将其作为字节流传输到另一台机器,然后从接收到的缓冲区中获取该值,则两台机器将具有相同的 32 位值,无论它们是否具有相同或不同的本机字节骑马。需要强制转换,因为默认促销只会转换为int
,它可能小于 a uin32_t
,在这种情况下,移位可能超出范围。
char
如果您的缓冲区不是(char 可能会或可能不会被签名),请小心uint8_t
- 在这种情况下您需要屏蔽:
uint32_t get32(char *buf) {
return ((uint32_t)buf[0] & 0xff) + (((uint32_t)buf[1] & 0xff) << 8) +
(((uint32_t)buf[2] & 0xff) << 16) + (((uint32_t)buf[3] & 0xff) << 24);
}
推荐阅读
- ios - 在应用内购买中按下购买按钮时如何检测和执行代码
- javascript - 在 HOC 中使用 Antd 菜单时出现“超出最大调用堆栈大小”
- angular - 服务器未能验证请求。确保 Authorization 标头的值正确形成,包括签名。错误?
- express - 如何使用 chai 测试 multipart/form-data
- python - 将数据插入数据库时如何修复```TypeError: can't pickle _thread._local object```?
- uwp - 为什么 UWP TextBlock 是密封的?
- php - 如何制作不同的 layout.php 文件并包含到不同的语言中?
- macros - 手动生成 xlsx 的宏可以正常工作,但不能通过 QlikviewManagement Consol 批量生成
- kotlin - 切换到 Kotlin 1.3.30 仅在 Android API 21 上中断 hashCode
- sql-server - SQL Server Native Client Datetime field overflow during migration