Java 如何从C/C+;调用getter返回二维数组+;?

Java 如何从C/C+;调用getter返回二维数组+;?,java,c++,arrays,java-native-interface,Java,C++,Arrays,Java Native Interface,我对JNI有问题。我想调用getter(通过JNI)返回二维数组,并在C/C++中处理这个数组 在Java中,我实现了以下类: package eu.cbridge; ... public class LDIContainer { private double[][] doubleData; ... public double[][] getDoubleData() { return doubleData; } ... } 在C/C+

我对JNI有问题。我想调用getter(通过JNI)返回二维数组,并在C/C++中处理这个数组

在Java中,我实现了以下类:

package eu.cbridge;
...

public class LDIContainer {
    private double[][] doubleData;   
    ...

    public double[][] getDoubleData() {
       return doubleData;
   }
   ...
}
在C/C++中,实现了以下本机方法:

JNIEXPORT void JNICALL Java_eu_cbridge_CWrapper_transferData__Leu_cbridge_LDIContainer
   (JNIEnv *env, jobject, jobject) {

   //Get class identifier 
   jclass cls = env->FindClass("eu/cbridge/LDIContainer");

   // Get method ID 
   jmethodID mid = env->GetMethodID(cls, "getDoubleData", "()[[D");

   // Call Java method
   jobject mvdata = env->CallObjectMethod(cls, mid); // Causes an access violation in C!!!

   ...

   }
此外,我想处理返回的二维数组。然而,我可以访问类(cls)并获取jmethodID(mid)。当我调用该方法时,我得到访问冲突异常:(


有人知道如何使用对象的getter从Java对象中获取二维数组吗?

我会将2d数组展平到1d,然后发送它。它应该比单独发送每一行性能更好


我会将2d数组展平到1d,然后再发送。它应该比单独发送每行性能更好


您正在使用Java类而不是Java对象调用
CallObjectMethod

//Get class identifier 
jclass cls = env->FindClass("eu/cbridge/LDIContainer");

// Get method ID 
jmethodID mid = env->GetMethodID(cls, "getDoubleData", "()[[D");

// Call Java method
jobject mvdata = env->CallObjectMethod(cls, mid); // Causes an access violation in C!!!
是的,我打赌这会导致访问冲突。看到了吗


你还没有提供详细信息(有些人会说你应该为此投下一两张否决票…),而你在问题中输入的代码甚至不会编译(甚至更多的人会说你应该为发布甚至不会编译的代码投下十几张否决票…),但我怀疑传递给方法的
jobject
对象之一是包含二维数组的适当类的对象。

您使用Java类而不是Java对象调用
CallObjectMethod

//Get class identifier 
jclass cls = env->FindClass("eu/cbridge/LDIContainer");

// Get method ID 
jmethodID mid = env->GetMethodID(cls, "getDoubleData", "()[[D");

// Call Java method
jobject mvdata = env->CallObjectMethod(cls, mid); // Causes an access violation in C!!!
是的,我打赌这会导致访问冲突。看到了吗


你还没有提供详细信息(有些人会说你应该为此投下一两张否决票…),而你在问题中输入的代码甚至不会编译(甚至更多的人会说你应该为发布甚至不会编译的代码投下十几张否决票…),但我怀疑传递给方法的
jobject
对象中有一个是包含二维数组的适当类的对象。

您需要分解外部数组。在JNI中,您只支持1D数组。移动到更高维度后,您必须从对象中检索内容,只要有m超过1D。请看下面:

#include <stdio.h>
#include "jni.h"
#include "recipeNo039_PassArray2D.h"

JNIEXPORT int JNICALL Java_recipeNo039_PassArray2D_displayArray2D
  (JNIEnv *env, jclass obj) {

  /* Get objarg's class - objarg is the one we pass from
     Java */
  jclass cls = (*env)->GetObjectClass(env, obj);

  /* Remember that you can alway get method signature using javap tool
     > javap -classpath target -s -p recipeNo039.PassArray2D | grep -A +1 getDoubleData
         public double[][] getDoubleData();
           descriptor: ()[[D
  */

  jmethodID mid =
    (*env)->GetMethodID(env, cls, "getDoubleData", "()[[D");

  /* We have to make sure that method exists */
  if (mid == NULL) {
    return -1; /* method not found */
  }

  /* Now, it's time for getting array of arrays */
  jobject objArray = (*env)->CallObjectMethod(env, obj, mid);

  /* We will iterate over the array so we can get into next array */
  int arraySize = (*env)->GetArrayLength(env, objArray);

  /* We want to go over all elements (all sub arrays) */
  for (int i=0; i < arraySize; i++)
  {
    jdoubleArray array = (*env)->GetObjectArrayElement(env, objArray, i);

    /* get size of the array */
    jsize len = (*env)->GetArrayLength(env, array);

    /* get the body of array; it will be referecende by C pointer */
    jdouble *body = (*env)->GetDoubleArrayElements(env, array, 0);

    /* do some stuff */
    for(int p=0; p < len; p++) {
      printf("Double value [%d;%d]: %f\n", i, p, body[p]);
    }

    /* release body when you decide it is no longer needed */
    (*env)->ReleaseDoubleArrayElements(env, array, body, 0);
  }

  return 0;

}
#包括
#包括“jni.h”
#包括“recipeNo039_PassArray2D.h”
JNIEXPORT int JNICALL Java\u recipeNo039\u PassArray2D\u displayArray2D
(JNIEnv*env,jclass obj){
/*获取objarg的类-objarg是我们从中传递的类
爪哇*/
jclass cls=(*env)->GetObjectClass(env,obj);
/*请记住,您总是可以使用javap工具获取方法签名
>javap-classpath target-s-p recipeNo039.PassArray2D | grep-A+1 getDoubleData
public double[]getDoubleData();
描述符:()[[D]
*/
杰米索德米德=
(*env)->GetMethodID(env,cls,“getDoubleData”,“()[[D”);
/*我们必须确保该方法存在*/
if(mid==NULL){
未找到return-1;/*方法*/
}
/*现在,是获取数组数组的时候了*/
jobject-objArray=(*env)->CallObjectMethod(env,obj,mid);
/*我们将迭代数组,以便进入下一个数组*/
int arraySize=(*env)->GetArrayLength(env,objArray);
/*我们要检查所有元素(所有子数组)*/
for(int i=0;iGetObjectArrayElement(env,objArray,i);
/*获取数组的大小*/
jsize len=(*env)->GetArrayLength(env,数组);
/*获取数组体;它将被C指针引用*/
jdouble*body=(*env)->GetDoubleArrayElements(env,数组,0);
/*做点什么*/
对于(int p=0;p释放双数组元素(env,数组,body,0);
}
返回0;
}
首先,您需要获取表示数组数组的对象,然后,您必须迭代它的所有元素并检索内容


您可以在此处找到完整的示例代码:

您需要分解外部数组。在JNI中,您只支持1D数组。在移动到更高维度后,您必须检索内容表单对象,只要您的维度超过1D,就可以向下移动。请看下面的内容:

#include <stdio.h>
#include "jni.h"
#include "recipeNo039_PassArray2D.h"

JNIEXPORT int JNICALL Java_recipeNo039_PassArray2D_displayArray2D
  (JNIEnv *env, jclass obj) {

  /* Get objarg's class - objarg is the one we pass from
     Java */
  jclass cls = (*env)->GetObjectClass(env, obj);

  /* Remember that you can alway get method signature using javap tool
     > javap -classpath target -s -p recipeNo039.PassArray2D | grep -A +1 getDoubleData
         public double[][] getDoubleData();
           descriptor: ()[[D
  */

  jmethodID mid =
    (*env)->GetMethodID(env, cls, "getDoubleData", "()[[D");

  /* We have to make sure that method exists */
  if (mid == NULL) {
    return -1; /* method not found */
  }

  /* Now, it's time for getting array of arrays */
  jobject objArray = (*env)->CallObjectMethod(env, obj, mid);

  /* We will iterate over the array so we can get into next array */
  int arraySize = (*env)->GetArrayLength(env, objArray);

  /* We want to go over all elements (all sub arrays) */
  for (int i=0; i < arraySize; i++)
  {
    jdoubleArray array = (*env)->GetObjectArrayElement(env, objArray, i);

    /* get size of the array */
    jsize len = (*env)->GetArrayLength(env, array);

    /* get the body of array; it will be referecende by C pointer */
    jdouble *body = (*env)->GetDoubleArrayElements(env, array, 0);

    /* do some stuff */
    for(int p=0; p < len; p++) {
      printf("Double value [%d;%d]: %f\n", i, p, body[p]);
    }

    /* release body when you decide it is no longer needed */
    (*env)->ReleaseDoubleArrayElements(env, array, body, 0);
  }

  return 0;

}
#包括
#包括“jni.h”
#包括“recipeNo039_PassArray2D.h”
JNIEXPORT int JNICALL Java\u recipeNo039\u PassArray2D\u displayArray2D
(JNIEnv*env,jclass obj){
/*获取objarg的类-objarg是我们从中传递的类
爪哇*/
jclass cls=(*env)->GetObjectClass(env,obj);
/*请记住,您总是可以使用javap工具获取方法签名
>javap-classpath target-s-p recipeNo039.PassArray2D | grep-A+1 getDoubleData
public double[]getDoubleData();
描述符:()[[D]
*/
杰米索德米德=
(*env)->GetMethodID(env,cls,“getDoubleData”,“()[[D”);
/*我们必须确保该方法存在*/
if(mid==NULL){
未找到return-1;/*方法*/
}
/*现在,是获取数组数组的时候了*/
jobject-objArray=(*env)->CallObjectMethod(env,obj,mid);
/*我们将迭代数组,以便进入下一个数组*/
int arraySize=(*env)->GetArrayLength(env,objArray);
/*我们要检查所有元素(所有子数组)*/
for(int i=0;iGetObjectArrayElement(env,objArray,i);
/*获取数组的大小*/
jsize len=(*env)->GetArrayLength(env,数组);
/*获取数组体;它将被C指针引用*/
jdouble*body=(*env)->GetDoubleArrayElements(env,数组,0);
/*做点什么*/
对于(int p=0;p释放双数组元素(env,数组,body,0);
}
返回0;
}
首先,你需要