我应该如何在 jna 中按值从 Java 传递和返回 unsigned int 到 C/C++

Posted

技术标签:

【中文标题】我应该如何在 jna 中按值从 Java 传递和返回 unsigned int 到 C/C++【英文标题】:How should I pass and return unsigned int by value from Java to C/C++ in jna 【发布时间】:2015-11-05 12:02:13 【问题描述】:

我的 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)有效的值时,这显然会出现问题;解决此问题的推荐方法是什么? One answer elsewhere 推荐“IntByReference”,但除非我误解了,否则他们说的是 long*,而不是按值传递的实际 unsigned int。

(这是精简的示例代码,如果有语法错误,请在 cmets 中告诉我,我会更新问题)

【问题讨论】:

C 不是 C++ 不是 C! @Olaf 虽然是真的,但这个答案对 C 和 C++ 都适用,所以只关注 C 和 Java 标签的人可以回答它;需要为 C API 解决此问题的人也可以使用答案;但感谢您提醒我需要将 extern C 放在通话中。 如果一定要加extern "C" ... ,那就不是C++了。无论哪种方式,只有一个标签是正确的。 “标牌”是什么意思?这可能是一个签名问题。我不知道 Java,但如果它没有无符号类型,则需要空间用于 C 中的额外位 unsigned 提供一个方向,或者必须断言该值永远不会在另一个方向上为负。 只需更改“C++ 函数”,使其使用int 而不是unsigned int。这样就不会出现接口不匹配的情况。试图通过不匹配的接口找到黑客来工作很容易出错,并且在系统之间移植代码时可能会失败。由于 Java 不支持无符号类型,因此 C++ 代码必须处理转换,而不是试图依赖于接口规范中魔法发生的转换。 @Peter Sure,但这“破坏”了 C# 也使用的互操作性接口,只是为了支持 Java 缺少的类型。更重要的是,由于 JNA 库是专门为解决互操作而设计的,因此它必须有一种推荐的方式来与使用 unsigned int 的 锁定 API 进行交互 【参考方案1】:

JNA provides the IntegerType class,可用于表示某个特定大小的无符号整数。您必须使用 Java long 以原始形式保存本机 unsigned int,因为它的值可能超出 Java int 的范围,但通常您可以传递 IntegerType 对象并且仅根据需要提取原始值。

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

【讨论】:

以上是关于我应该如何在 jna 中按值从 Java 传递和返回 unsigned int 到 C/C++的主要内容,如果未能解决你的问题,请参考以下文章

在lisp中按值传递参数

如何在 C# 字典中按值索引过滤项目?

为啥要在 C++ 中按值传递对象 [重复]

为啥我要在 C 中按值传递函数参数?

是否传递指针参数,在 C++ 中按值传递?

在 Ruby 中按值传递是啥意思? [复制]