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

Kotlin字节序问题排查:跨平台字节数组反序列化异常

字节序不匹配导致长整型反序列化错误排查

问题背景

  • 运行在Ubuntu上的C++应用以小端序序列化长整型数据,例如数值1000L被序列化为字节数组[-24, 3, 0, 0, 0, 0, 0, 0]。
  • MacOS M1芯片编译的Android应用(Kotlin)中,系统原生字节序为小端,但使用默认ByteBuffer转换时,1000L被序列化为[0,0,0,0,0,0,3,-24](大端序);反序列化C++传来的字节数组时,得到异常值-1728537831980138496而非预期的1000L。

核心原因

ByteBuffer的默认字节序是大端序(BIG_ENDIAN),与系统原生字节序无关。即使你的Android设备是小端架构,直接使用未指定字节序的ByteBuffer,会默认按大端规则处理字节数组,导致与C++的小端数据格式不匹配,最终转换出错误数值。

解决方案

修改Kotlin的字节数组与长整型转换函数,明确指定ByteBuffer使用小端序,与C++端的序列化规则保持一致:

fun isLittleEndian(): Boolean {
    return ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN
}

/**
 * 将长整型转换为小端序字节数组
 */
fun Long.toBytes(): ByteArray {
    return ByteBuffer.allocate(Long.SIZE_BYTES)
        .order(ByteOrder.LITTLE_ENDIAN) // 指定小端序
        .putLong(this)
        .array()
}

/**
 * 将小端序字节数组转换为长整型
 */
fun ByteArray.toLong(): Long {
    return ByteBuffer.wrap(this)
        .order(ByteOrder.LITTLE_ENDIAN) // 指定小端序
        .long
}

fun test() {
    val longNumber = 1000L
    val isLittleEndian = isLittleEndian() // 返回true
    val bytes = longNumber.toBytes()      // 输出:[-24, 3, 0, 0, 0, 0, 0, 0],与C++一致
    val restoredNumber = bytes.toLong()   // 输出:1000L,符合预期
}

额外说明

如果需要跨平台兼容性,也可以统一使用网络字节序(大端序),此时C++端需要将数据转换为大端后再序列化,Kotlin端保持默认ByteBuffer即可,但需要确保两端规则完全统一。

内容的提问来源于stack exchange,提问作者Nguyen Minh Binh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 04:26:18