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
相关产品推荐
相关产品推荐

