我该如何在Java中使用JNA将无符号整数通过值传递到C/C++并返回?

6

我的C++函数

extern "C" {
   DECLSPEC unsigned int STDCALL doNumberThing(unsigned int some_number);
}

我的Java接口

package com.myplace.nativeapi;

import com.sun.jna.Library;
import com.sun.jna.Memory;
import com.sun.jna.Pointer;

interface NativeAPI extends Library {
    int doNumberThing(int some_number);
}

显然在处理仅适用于不匹配类型之一(int vs unsigned int)的值时存在问题。有什么推荐的方法来解决这个问题?在另一个答案中,推荐使用“IntByReference”,但除非我误解了,否则他们谈论的是long*,而不是传递的实际unsigned int值。
(这是缩减示例代码,如果有语法错误,请在评论中告诉我,我会更新问题)

1
C不是C++,C++也不是C! - too honest for this site
2
@Olaf,虽然如此,这个答案适用于C和C++,所以只关注C和Java标签的人也可以回答它;需要为C API解决此问题的人也可以使用这些答案;但感谢您提醒我需要在调用周围加上extern C。 - deworde
2
如果你必须添加extern "C"{...},那就不是C++。无论如何,只有一个标签是正确的。而你所说的“标志”是什么意思呢?很可能是符号问题。我不懂Java,但如果它没有无符号类型,你需要为C提供的一位额外的unsigned比特腾出空间,或者断言该值在另一个方向上永远不为负数。 - too honest for this site
3
只需修改"C++函数",让它使用int而不是unsigned int,这样就不会出现接口不匹配的情况。试图通过接口不匹配的技巧来解决问题是容易出错的,而且在移植代码时很可能失败。由于Java不支持无符号类型,因此C++代码必须处理转换,而不能依靠接口规范中的魔法转换。 - Peter
1
@Peter 当然可以,但这会“破坏”互操作接口,该接口也被C#使用,仅为了支持Java缺失的类型。更重要的是,由于JNA库专门设计用于解决交互问题,因此必须有一种推荐的方法来与使用无符号整数的锁定API进行交互。 - deworde
显示剩余13条评论
1个回答

5

JNA提供了IntegerType, 可用于表示特定大小的无符号整数。您需要使用Java long来保存原生unsigned int,因为其值可能超出Javaint的范围,但通常可以传递IntegerType对象并仅在需要时提取原始值。

public class UnsignedInt extends IntegerType {
    public UnsignedInt() {
         super(4, true);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接