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

Java JNA调用本地函数后ByteBuffer返回负值问题求助

JNA调用DLL时ByteBuffer字节值显示异常问题

我通过JNA调用DLL中的本地C函数,函数定义如下:

short sSmartISOEx(USHORT usInDataLen, const UCHAR *pucDataIn, USHORT *pusOutDataLen, UCHAR *pucDataOut);

在Java中声明为:

short sSmartISOEx(short usInDataLen, ByteBuffer pucDataIn, ShortBuffer pusOutDataLen, ByteBuffer pucDataOut);

调用时传入指定长度的ByteBuffer pucDataIn,预期获取长度为pusOutDataLen的ByteBuffer pucDataOut。函数能正常工作,但执行以下代码输出结果不符合预期:

System.out.println("first byte: " + pucDataOut.get(0));
System.out.println("second byte: " + pucDataOut.get(1));

预期第一个字节为0x69、第二个为0x86,实际输出:

first byte: 105
second byte: -122

105对应0x69是正确的,但-122对应0xffffff86,为什么pucDataOut.get(1)返回的是类似4字节的值?怎么才能得到包含0x69和0x86的正确字节数组?


问题原因

Java中的byte类型是有符号8位整数,范围是-128到127;而C语言中的UCHAR是无符号8位整数,范围0到255。当C侧返回0x86(十进制134)时,这个值超过了Java有符号byte的最大值127,会被解释为有符号补码值-122。

你看到的0xffffff86其实是Java将该有符号byte自动提升为int类型时的符号位扩展结果,并非ByteBuffer中存储了4字节数据,只是输出时的类型转换导致的视觉差异。

解决方法

1. 获取无符号字节值

如果要得到对应0x86的无符号数值,只需将byte与0xFF做按位与操作,消除符号位扩展的影响:

// 获取第一个字节的无符号值(0x69 → 105)
int firstByte = pucDataOut.get(0) & 0xFF;
// 获取第二个字节的无符号值(0x86 → 134)
int secondByte = pucDataOut.get(1) & 0xFF;
System.out.println("first byte: " + firstByte); // 输出105
System.out.println("second byte: " + secondByte); // 输出134
// 转成十六进制显示更直观
System.out.println("first byte (hex): " + Integer.toHexString(firstByte)); // 输出69
System.out.println("second byte (hex): " + Integer.toHexString(secondByte)); // 输出86

2. 生成正确的字节数组

如果需要提取完整的字节数组,直接调用ByteBuffer.array()即可(前提是ByteBuffer基于数组创建,比如用ByteBuffer.allocate()生成):

byte[] resultArray = pucDataOut.array();
// 若要得到无符号数值数组,遍历转换
int[] unsignedArray = new int[resultArray.length];
for (int i = 0; i < resultArray.length; i++) {
    unsignedArray[i] = resultArray[i] & 0xFF;
}

如果ByteBuffer是直接内存缓冲区(非基于数组),可以手动读取每个字节:

int outLen = pusOutDataLen.get(0); // 先获取输出长度
byte[] resultArray = new byte[outLen];
pucDataOut.position(0); // 重置缓冲区位置
pucDataOut.get(resultArray);
// 转换为无符号数值数组
int[] unsignedArray = new int[outLen];
for (int i = 0; i < outLen; i++) {
    unsignedArray[i] = resultArray[i] & 0xFF;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 10:21:04