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

Posted 跨链技术践行者

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java - 在 C++ 中的 Java Native (JNI) 方法中在 jdoubleArray 和 vector<double> 之间进行转换相关的知识,希望对你有一定的参考价值。

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

我的具体问题如下:我的 C++ 本地方法从我的 Java 程序接收一个 jdoubleArray,它需要映射到一个 C++ vector ,然后可以传递给 C++ dll 中的一个方法。 dll 中的方法返回另一个 vector ,然后需要将其映射到新的 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;
 

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

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

我需要了解的是

任何帮助,将不胜感激!

最佳答案

根据文档,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] );

关于java - 在 C++ 中的 Java Native (JNI) 方法中在 jdoubleArray 和 vector<double> 之间进行转换,我们在Stack Overflow上找到一个类似的问题: Converting between jdoubleArray and vector<double> in a Java Native (JNI) method in C++ - Stack Overflow

以上是关于java - 在 C++ 中的 Java Native (JNI) 方法中在 jdoubleArray 和 vector<double> 之间进行转换的主要内容,如果未能解决你的问题,请参考以下文章

C、C++、Java、C# 中的 main()

JNI - C++/Java 中的侦听器 - 是不是可以在 C++ 中实例化 Java 对象并将它们用作参数

如何在 C++ 中实现方法返回类似 Java 中的对象 [关闭]

为啥继承在 Java 和 C++ 中的行为不同,超类调用(或不调用)子类的方法?

C++ 中的析构函数(与 java 相比)

如何在 C、java 和 C++ 中的任何位置编译和运行任何文件?