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

如何在CMake中生成包含空字节(NUL byte)的字符串?

CMake: 解决十六进制字符串转回二进制文件的空字节问题

CMake里用file(READ <filename> <variable> HEX)把二进制文件转成十六进制字符串确实很方便,但反向操作就没那么直接了——毕竟file(WRITE ...)只是单纯写入字符串内容,没法直接把十六进制串还原成原始二进制。

我见过不少人尝试先把十六进制字符串拆成十进制数字列表,再用string(ASCII ${bytes} bytes)来转成二进制内容,但这里有个致命问题:一旦内容里有空字节(\0),CMake的string(ASCII)就会直接罢工,因为它会把空字节当成字符串的结束标记,导致后面的内容全部丢失。

那怎么处理这个问题呢?我写了个小的CMake函数来搞定它,核心思路是逐字节处理,绕开string(ASCII)的限制:

function(hex_to_binary hex_string output_path)
    # 先校验十六进制字符串长度必须是偶数,每个字节对应两位十六进制字符
    string(LENGTH "${hex_string}" hex_length)
    math(EXPR remainder "${hex_length} % 2")
    if(remainder EQUAL 1)
        message(FATAL_ERROR "Input hex string has an odd length, which is invalid!")
    endif()

    # 初始化输出文件为空
    file(WRITE "${output_path}" "")
    math(EXPR total_bytes "${hex_length} / 2")

    # 逐字节解析并写入
    foreach(index RANGE 0 ${total_bytes})
        if(index EQUAL ${total_bytes})
            break()
        endif()
        math(EXPR start_pos "${index} * 2")
        # 截取两位十六进制字符
        string(SUBSTRING "${hex_string}" ${start_pos} 2 current_hex)
        # 转大写避免大小写问题,再转成十进制
        string(TOUPPER "${current_hex}" current_hex_upper)
        math(EXPR current_byte "0x${current_hex_upper}")
        # 用Perl风格替换直接写入单个字节,完美处理空字节
        file(APPEND "${output_path}" [==[${current_byte}]==] USE_PERL_STYLE)
    endforeach()
endfunction()

用法示例:
假设你已经通过file(READ "input.bin" my_hex_str HEX)得到了十六进制字符串my_hex_str,只需要调用:

hex_to_binary("${my_hex_str}" "restored_output.bin")

就能得到和原文件完全一致的二进制文件,包括其中的空字节。

这个方法避开了string(ASCII)的局限性,直接通过文件追加的方式写入每个字节,不管是空字节还是其他特殊字符都能正确处理。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:49:02