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

JNI开发中unsigned char数组转jstring返回Java时长度随机异常

unsigned char数组转jstring时字符串长度随机异常问题

问题场景

Java调用共享C库的JNI开发场景中,被调用的C库函数返回unsigned char*类型结果,JNI接口需要将其转换为jstring类型返回给Java层。

异常现象

最初尝试直接强转类型后调用NewStringUTF完成转换,代码如下:

return (env)->NewStringUTF((char*) unsigned_char_array);

实际运行时,本应只有20字节有效内容的数组,返回Java层后得到的字符串长度随机为21、22甚至23字节,仅前20字节内容符合预期。

复现代码

JNIEXPORT jstring JNICALL Java_com_example_demo_DemoClass_functionToCall
  (JNIEnv *env, jobject, ) {
  // 按照库函数要求定义unsigned char数组
  unsigned char unsigned_char_array[20];
  // 调用库函数填充数组内容
  function_to_call(unsigned_char_array);

  // 调试打印C端结果
  printf("result : %.*s (%ld chars)\n", (int) sizeof unsigned_char_array, unsigned_char_array, (int) sizeof unsigned_char_array);
  // C端打印结果符合预期:输出20位数字字符串,例如92311221679609987114

  // 尝试转换为jstring返回Java层
  return (env)->NewStringUTF((char*) unsigned_char_array);
  // Java层调试获取到的字符串长度异常,为21/22/23字节不等
}

Java端异常长度字符串调试截图
C端通过printf指定长度打印的结果完全符合预期,为20位数字字符串,但Java端获取的字符串长度始终超出20字节,且多余内容随机。

问题原因

NewStringUTF方法要求传入的是标准C风格以\0作为终止符的UTF-8字符串,定义的unsigned char unsigned_char_array[20]是固定20字节长度的栈数组,没有为字符串终止符\0预留空间,NewStringUTF读取完20字节有效内容后,会继续向后读取相邻栈内存的随机数据,直到遇到\0才停止,最终导致返回的字符串长度随机、尾部带多余乱码内容。
C端调试时printf使用了%.*s格式手动指定打印长度为20字节,不会读取数组外的内存,因此打印结果正常。

解决方案

可选择以下任意一种方式修复:

  • 为数组预留终止符空间,填充完有效内容后手动追加\0
    将数组长度调整为21字节,最后1字节填充0作为字符串终止符,再调用NewStringUTF即可:
    unsigned char unsigned_char_array[21]; // 多分配1字节存储终止符
    function_to_call(unsigned_char_array);
    unsigned_char_array[20] = '\0'; // 手动追加字符串终止符
    return env->NewStringUTF((char*)unsigned_char_array);
    
  • 不依赖\0终止符,使用明确长度参数构造jstring,无需修改原数组大小:
    jchar buf[20];
    for (int i = 0; i < 20; i++) {
        buf[i] = (jchar)unsigned_char_array[i];
    }
    return env->NewString(buf, 20); // 明确指定有效长度为20字节
    
    注意:如果数组存储的是UTF-8编码的多字节字符,优先使用第一种追加终止符的方案,避免出现字符截断问题;如果存储的是单字节ASCII字符(比如本场景中的纯数字内容),两种方案均可正常使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:27:18