我有C ++ App,它调用了一些java功能。我正在使用JNI。一切正常,但仍有一个小问题。在C ++ App中,我有一些巨大的数组。 Java App也需要这些数据并返回一大堆结果。目前我只是复制数据(你可以查看下面的代码和平)。如果我直接从每个指针从Java App访问这些数组会更好。可能吗?我假设没有(因为JVM),但在这种情况下我必须向我的老板详细解释:)所以,是或否,以及如何或为什么?
jdoubleArray in2 = env->NewDoubleArray(1000);
jdouble *elems2 = (jdouble*)calloc(1000, sizeof(jdouble));
for(int i = 0; i < 1000; i++)
{
elems2[i] = (jdouble)inputArray[i];
}
env->SetDoubleArrayRegion(in2, 0, 1000, elems2);
if(midCD != NULL)
{
jdouble res1 = env->CallStaticDoubleMethod(cls, midCD, in2);
double res1c = res1;
printf("C++.Res1: %f\n", res1c);
}
答案 0 :(得分:3)
为此目的,在Java 1.4中引入了直接ByteBuffers。与Java一起的新类是corresponding JNI functions。您可以将本机数组包装在ByteBuffer(以及相应的IntBuffer等视图)中,并在不进行复制的情况下进行读写。
答案 1 :(得分:1)
您可以做的最好的事情是使用Get<PrimitiveType>ArrayElements routines。希望VM支持pinning:
jdoubleArray in2 = env->NewDoubleArray(1000);
jboolean isCopy;
jdouble *elems2 = env->GetDoubleArrayElements(in2, &isCopy);
for(int i = 0; i < 1000; i++)
{
elems2[i] = (jdouble)inputArray[i];
}
env->ReleaseDoubleArrayElements(in2, elems2, 0);
elems2 = NULL;
如果在调用GetDoubleArrayElements()之后isCopy
为JNI_FALSE
,则表示没有复制。
编辑:重新阅读您的问题后,您可能需要考虑实施Archie's idea。这取决于Java方法如何使用数据。如果Java方法不使用整个数组,或者不是同时使用整个数组,那么Archie的创建C ++数组的Java类包装器(使用本机访问器)的解决方案可能是一个很好的解决方案。但是,如果Java方法需要所有数据,那么您可能只需要以最快的方式将数据导入VM,GetDoubleArrayElements()提供了这些数据。
如果您对C ++数组的某些元素进行了更改,并希望对Java副本进行相同的更改,那么SetDoubleArrayRegion()就会发挥作用。
EDIT2:我相信Archie指的是:
public class NativeDoubleArrayProxy {
// This is the native `inputArray' pointer.
private long p;
private int length;
private NativeDoubleArrayProxy(long p, int length) {
this.p = p;
this.length = length;
}
public int length() {
return length;
}
public native double getDouble(int index);
public native void getDoubles(int startingIndex, double[] out, int outOffset, int length);
}
具体细节取决于inputArray
的类型(是原始的C风格数组,还是std::vector<double>
,还有其他什么?)。但是我的想法是在JNI端构造一个NativeDoubleArrayProxy
对象,并将指针转换为jlong
。 getDouble()和getDoubles()的JNI实现实现了从C ++到Java代码的复制。
当然,您需要非常小心以确保指针保持有效。
另请参阅:What is the 'correct' way to store a native pointer inside a Java object?