可以将 Java 数组传递给采用数组的 C/C++ 函数吗?

Posted

技术标签:

【中文标题】可以将 Java 数组传递给采用数组的 C/C++ 函数吗?【英文标题】:Can a Java array be passed to a C/C++ function which takes an array? 【发布时间】:2016-11-04 09:44:36 【问题描述】:

我现在正在学习 JNI。假设我有一个 C/C++ 库函数,它将 int* 数组作为输入(我们假设 int 是 4 个字节,并且就像在 Java 中一样有符号),即作为指针传递的数组。是否可以通过 JNI 将一个 int 的 Java 数组传递给这样的函数,而不进行任何复制(显然我们在这样做时删除了 Java 数组的长度部分)?直接 ByteBuffer 是做这些事情的唯一可行方法吗?

【问题讨论】:

【参考方案1】:

正如您提到的那样,直接ByteBuffer 是避免复制的一种方式。

如果您传递一个 Java 数组,您将需要调用 Get<Primitive>ArrayElements,它可能也可能不复制(或 Get<Primitive>ArrayRegion,但这没有任何意义,因为它总是复制)。

还有GetPrimitiveArrayCritical,如果您只需要在“短”时间内访问元素,并且不需要在释放元素之前执行任何其他 JNI 调用,则可以使用它。它比Get<Primitive>ArrayElements“更有可能”不复制。

一个例子:

jint len = env->GetArrayLength(myIntArray);
jint *elements = env->GetPrimitiveArrayCritical(myIntArray, NULL);

// Use elements...

env->ReleasePrimitiveArrayCritical(myIntArray, elements, 0);  

见Oracle's JNI documentation。

【讨论】:

那么,基本上直接 ByteBuffer 是实现这一目标的唯一可靠方法吗? 我猜是这样,除非你只针对特定的虚拟机,你知道它会以某种方式运行。

以上是关于可以将 Java 数组传递给采用数组的 C/C++ 函数吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 C/C++ 中传递二维数组时出错

JNI内两种方式从C/C++中传递一维二维三维数组数据至Java层详细梳理

无法将 char *[2] 类型的数组的地址传递给采用 char *** 的函数

我可以将字符串数组(String [] [])的数组传递给Java中的函数吗? [复制]

如何将 Swift 字符串数组传递给采用 char ** 参数的 C 函数

如何将字节数组从android java类传递给JNI C NDK?