Java 将float[]传递给C++;经由JNI

Java 将float[]传递给C++;经由JNI,java,c++,java-native-interface,Java,C++,Java Native Interface,在我的Java代码中,我有一个2D浮点数组float[x][4]floatArray。此处x可以介于1和25之间。我必须通过JNI将这个二维浮点数组传递给C++方法。我的JNI方法是 jboolean MyJNIMethod(JNIEnv * env, jobject obj, jobjectArray myArray) { //how to convert this myArray to something that can be safely passed to C++ method

在我的Java代码中,我有一个2D浮点数组
float[x][4]floatArray
。此处
x
可以介于1和25之间。我必须通过
JNI
将这个二维浮点数组传递给
C++
方法。我的
JNI
方法是

jboolean MyJNIMethod(JNIEnv * env, jobject obj, jobjectArray myArray)
{
    //how to convert this myArray to something that can be safely passed to C++ method below
}
MyJNIMethod
中,我必须调用
C++
方法,并将从Java获取的2D浮点数组传递给该方法

bool MyCplusPlusMethod(float coordinates[][4])
    {

    }

由于缺乏本地开发知识,我很难正确地将jobject转换为float[]]。有人能告诉我最简单最安全的方法吗?谢谢

像这样的方法应该会奏效:

jboolean MyJNIMethod(JNIEnv * env, jobject obj, jobjectArray myArray)
{
  int len1 = env -> GetArrayLength(myArray);
  jfloatArray dim=  (jfloatArray)env->GetObjectArrayElement(myArray, 0);
  int len2 = env -> GetArrayLength(dim);
  float **localArray;
  // allocate localArray using len1
  localArray = new float*[len1];
  for(int i=0; i<len1; ++i){
     jfloatArray oneDim= (jfloatArray)env->GetObjectArrayElement(myArray, i);
     jfloat *element=env->GetFloatArrayElements(oneDim, 0);
     //allocate localArray[i] using len2
     localArray[i] = new float[len2];
     for(int j=0; j<len2; ++j) {
        localArray[i][j]= element[j];
     }
  }
  //TODO play with localArray, don't forget to release memory ;)
}
在您的c代码中对应:

JNIEXPORT jboolean JNICALL Java_ClassName_methodName (JNIEnv *, jobject, jobjectArray);

以下是。

要释放分配的内存,您可以执行以下操作:

static void releaseMatrixArray(JNIEnv *env, jobjectArray matrix) {
int size = (*env)->GetArrayLength(env, matrix);
for (int i = 0; i < size; i++) {
    jfloatArray oneDim = (jfloatArray) (*env)->GetObjectArrayElement(env, matrix, i);
    jfloat *elements = (*env)->GetFloatArrayElements(env, oneDim, 0);

    (*env)->ReleaseFloatArrayElements(env, oneDim, elements, 0);
    (*env)->DeleteLocalRef(env, oneDim);
  }
}

我想问题是我如何通过JNI创建的动态2D浮点数组到一个采用浮点[]]的C++方法。我认为这是不可能的。它是?如果是,语法是什么?是的,这是可能的。请看我的示例localArray是指向二维本机数组的指针。如何申报取决于你自己。我的例子展示了如何用Java传递的数据填充它。我用float[][]localArray(我没有编译它)的位置更新了代码。我使用了这段代码,但不知道
env->releaseintarrayements(oneDim,element,JNI\u ABORT)
env->DeleteLocalRef(oneDim)
所以我得到了一个内存泄漏,直到我明白了这一点,你可以通过(在Java中)将2D Java数组转换为Java row major 1D数组,并将其传递到float[][4]来简化它。在C++中,1D和2D数组在内存中看起来相同。第二种建议是在JNI上传递一维数组。记住,你还需要通过这个大小。我决定在JNI和C++中使用向量。现在我正在阅读JNI中的float[][]。填充向量并将其传递给C++非常好的选择。您仍然可以使用我的示例;)
static void releaseMatrixArray(JNIEnv *env, jobjectArray matrix) {
int size = (*env)->GetArrayLength(env, matrix);
for (int i = 0; i < size; i++) {
    jfloatArray oneDim = (jfloatArray) (*env)->GetObjectArrayElement(env, matrix, i);
    jfloat *elements = (*env)->GetFloatArrayElements(env, oneDim, 0);

    (*env)->ReleaseFloatArrayElements(env, oneDim, elements, 0);
    (*env)->DeleteLocalRef(env, oneDim);
  }
}
free(localArray);