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),此时需要直接处理原始字节流:
- 如果你能直接获取C++传递的原始字节数组,直接用对应编码解码:
// 假设原始字节数组是rawBytes,C++用UTF-16LE编码 val fixedString = String(rawBytes, Charsets.UTF_16LE)
- 如果只能拿到错误解析的String,先将其转回字节数组(按UTF-8),再用正确编码解码:
val rawBytes = result.toByteArray(Charsets.UTF_8) val fixedString = String(rawBytes, Charsets.UTF_16LE)
内容的提问来源于stack exchange,提问作者rrr
相关产品推荐
相关产品推荐

