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

JNA传递byte数组给C函数出现乱码及长度异常问题求助

故障原因

C语言的字符串依赖末尾的\0(空终止符)判断结束边界:

  • 你直接传递Java的byte[]时,String.getBytes()生成的数组只包含字符串本身的字节内容,没有额外追加空终止符
  • C侧的strlen、printf("%s")都会持续读取内存直到遇到\0才停止,超出原byte数组的部分就是随机内存数据,所以会出现乱码、长度统计错误
  • 直接传String类型正常是因为JNA底层会自动给String参数追加空终止符后再传给C函数,但String对应的内存是不可修改的,所以不符合你的改写需求
可行解决方案

方案1:手动给byte数组追加空终止符(最常用)

在Java侧构造byte数组时,多分配1位长度留作空终止符即可,Java数组初始化时默认填充0,刚好对应C的\0:

/* load library*/
libPGM=loadLibrary(); // user defined function to load C library
    
String str = "Abcdefg";
// 显式指定字符集避免跨环境乱码
byte[] strBytes = str.getBytes(java.nio.charset.StandardCharsets.UTF_8);
// 构造带空终止符的数组
byte[] byteArr = new byte[strBytes.length + 1];
System.arraycopy(strBytes, 0, byteArr, 0, strBytes.length);

System.out.println("byte length is :"+strBytes.length);
String str_2=new String(strBytes, java.nio.charset.StandardCharsets.UTF_8);
System.out.println("Inside the java pgm "+str_2);

libPGM.foo(byteArr);

注意:如果你的C程序需要修改字符串内容,并且修改后的长度比原字符串长,需要根据实际业务场景提前给byte数组分配足够的长度,避免内存越界。

方案2:给C函数增加长度参数(更安全)

修改C函数额外接收一个长度参数,避免依赖空终止符判断边界,适合未知输入内容的场景:

void foo(unsigned char * inp, int len){
    setbuf(stdout, NULL);
    // 用指定长度打印字符串
    printf("data received is %.*s\n", len, inp);
    printf("The size is %d \n", len);
    // 改写内容时也以len作为边界判断,避免越界
}

Java侧调用时直接传原byte数组和数组长度即可:

libPGM.foo(byteArr, byteArr.length);

内容的提问来源于stack exchange,提问作者Alok Ranjan Swain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:24:02