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

如何正确将signed char[2]转换为uint16_t?CURL WebSocket回调关闭码计算异常求助

如何正确将signed char[2]转换为uint16_t?CURL WebSocket回调关闭码计算异常求助

哥们我太懂你这种踩有符号char坑的痛苦了!之前我在处理WebSocket关闭帧的时候也栽过一模一样的跟头,咱们先把问题根儿找出来,再给你搞定解决办法。

首先得搞明白你为啥得到奇怪的值:符号扩展在搞鬼!

你用的char是有符号类型(signed char),当你把负数(比如你例子里的data[1] = -24)参与移位运算时,C会自动把它提升为int类型。而负数的int是用补码表示的,高位全是1——比如-24作为signed char是0xE8,提升成int后就变成了0xFFFFFFE8。这时候你左移8位,得到的是0xFFFFE800,再和data[0](也就是0x03)按位或,结果就成了0xFFFFE803,这显然不是你想要的16位无符号关闭码。

那怎么解决?核心思路就是先把有符号char转成无符号的8位类型,再进行移位和拼接,彻底避免符号扩展的问题。给你两种靠谱的写法:

写法一:逐个强制转换为uint8_t

if (meta->flags & CURLWS_CLOSE) {
    // 先把每个signed char转成无符号的uint8_t,再拼接
    uint16_t reason = ( (uint8_t)data[1] << 8 ) | (uint8_t)data[0];
    // 这里就可以正常使用reason了
    ...
}

写法二:直接把指针转成unsigned char*

这种写法更清爽,适合处理更长的二进制数据:

if (meta->flags & CURLWS_CLOSE) {
    const unsigned char* udata = (const unsigned char*)data;
    uint16_t reason = (udata[1] << 8) | udata[0];
    ...
}

咱们拿你的例子验证一下:

  • data[1] = -24转成unsigned char后是0xE8(十进制232),左移8位得到0xE800
  • data[0] = 3转成unsigned char是0x03
  • 按位或之后得到0xE803,这就是正确的16位无符号关闭码了

另外提醒你一句:以后处理二进制数据(比如WebSocket帧、网络包)的时候,尽量都用unsigned char来操作,有符号类型的符号扩展真的是隐形坑,稍不注意就踩进去。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 10:14:31