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

Kotlin读取C++返回字符串长度异常(非空白字符翻倍)修复咨询

解决Kotlin从C++获取字符串长度翻倍的问题

核心修复方案

直接过滤掉字符串中的不可见空字符(\u0000)即可:

val fixedResult = result.filter { it != '\u0000' }
println(fixedResult.length) // 输出3,对应原"aBc"的正确长度
println(fixedResult.takeLast(2)) // 输出"Bc",符合预期

问题原因分析

你遇到的是典型的编码解析不匹配问题:

  • C++端返回的是UTF-16LE编码的宽字符串字节流(每个ASCII字符占2字节,格式为[字符字节][0x00])
  • Kotlin端错误地将其按UTF-8编码解析,导致每个2字节的宽字符被拆成两个UTF-8字符:原ASCII字符 + 不可见的空字符(\u0000)
  • 空白字符显示正常是因为空字符在终端/UI中不可见,但长度统计会把空字符算进去,所以非空白字符的长度看起来翻倍,而整体显示和原字符串一致。

你的测试例子完全符合这个逻辑:

  • "aBc"被解析为"a\u0000B\u0000c\u0000",长度6
  • 调用takeLast(5)时,取到的是"\u0000B\u0000c\u0000",空字符不显示,所以最终看到"Bc"

验证方法

可以先打印字符串中每个字符的Unicode编码,确认是否存在大量0(对应\u0000):

result.forEach { println("字符: '$it',编码: ${it.code}") }

如果输出中出现编码: 0的条目,就说明确实是空字符导致的问题。

特殊情况处理

如果过滤空字符后仍有问题(比如包含中文等非ASCII字符),说明C++端可能用了其他宽字符编码(如UTF-16BE),此时需要直接处理原始字节流:

  1. 如果你能直接获取C++传递的原始字节数组,直接用对应编码解码:
// 假设原始字节数组是rawBytes,C++用UTF-16LE编码
val fixedString = String(rawBytes, Charsets.UTF_16LE)
  1. 如果只能拿到错误解析的String,先将其转回字节数组(按UTF-8),再用正确编码解码:
val rawBytes = result.toByteArray(Charsets.UTF_8)
val fixedString = String(rawBytes, Charsets.UTF_16LE)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:43:23