在C++中的Java Native(JNI)方法中,在jdoubleArray和vector <double>之间进行转换

Rya*_*rgh 6 c++ java java-native-interface

我有一个C++ DLL,其中包含我需要在Java程序中使用的方法.我已经阅读了关于JNI的所有Sun文档,以及我在网上找到的大量教程,我似乎无法找到我的代码的问题.事实上,相当一部分代码是从各种教程和Sun网站剪切和粘贴的.

我的具体问题如下:我的C++本机方法从我的Java程序接收jdoubleArray,需要将其映射到c ++向量,然后可以将其传递给C++ dll中的方法.dll中的方法返回另一个向量,然后需要将其映射到新的jdoubleArray,并返回到Java程序.问题似乎是我没有正确执行映射.

我的代码如下(为简单起见,我删除了对dll方法的调用):

JNIEXPORT jdoubleArray JNICALL Java_jniarraypassing_JNIArrayPassing_passAndReturn(JNIEnv *env, jclass jcls, jdoubleArray arr)
{
     //First get a pointer to the elements within the jdoubleArray
     jsize len = env->GetArrayLength(arr);
     jboolean isCopy1;
     jdouble *body = env->GetDoubleArrayElements(arr, &isCopy1);

     //Create the vector<double> and reserve enough memory for mapping
     std::vector<double> newvector;
     newvector.reserve(len);

     //Copy the contents of the jdoubleArray to the vector<double>
     for (int i=0; i<len; i++)
     {
        newvector.push_back(body[i]);
     }

     //Release the pointer to the jdoubleArray
     if (isCopy1 == JNI_TRUE)
     {
        env->ReleaseDoubleArrayElements(arr, body, JNI_ABORT);
     }

     //Call the dll method here....

     jdoubleArray output = env->NewDoubleArray(newvector.size());
     jboolean isCopy2;
     jdouble* destArrayElems = env->GetDoubleArrayElements(output, &isCopy2);
     for (int i=0; i<newvector.size(); i++)
     {
        destArrayElems[i] = newvector[i];
     }
     if (isCopy2 == JNI_TRUE) 
     {
            env->ReleaseDoubleArrayElements(arr, destArrayElems, 0);
     }

     return output;
 }
Run Code Online (Sandbox Code Playgroud)

当我将body [i]的内容输出到控制台时,我得到一系列看起来非常像十六进制值的数字(例如003DFBE0),但它们都是相同的,所以我不认为它们可以是内存地址.

返回的jdoubleArray的内容完全由默认的double值(即0.0)组成,我怀疑是因为原始jdoubleArray中的值无效?

我需要知道的是,

任何帮助,将不胜感激!

Jam*_*nze 11

根据文档,GetDoubleArrayElements可能会返回指向副本的指针,而不是指向实际数据的指针; 这就是你需要打电话的原因ReleaseDoubleArrayElements.如果您正在复制,那么您没有看到您所写的值是正常的.如果您正在使用std::vector,我会使用GetDoubleArrayRegionSetDoubleArrayRegion:

jsize size = env->GetArrayLength( arr );
std::vector<double> input( size );
env->GetDoubleArrayRegion( arr, 0, size, &input[0] );

//  ...

jdoubleArray output = env->NewDoubleArray( results.size() );
env->SetDoubleArrayRegion( output, 0, results.size(), &results[0] );
Run Code Online (Sandbox Code Playgroud)

我认为这是初始化输出数组的唯一方法.