繁体   English   中英

C:将2D双数组转换为java 2D双数组

[英]C: Converting a 2D double array to a java 2D double array

我正在尝试在java中运行本机方法,然后接收我可以在java中使用的2D双数组。 我已经成功地操纵了C中的数据,但现在我需要将它发送回java。 如何将C中的2D双数组转换为java中的2D双数组?

我尝试过这个简单的代码,但是不幸的是它不起作用:

jobjectArray convertToArray(JNIEnv *env, double **data, int length1D,
            int *length2D) {
        jsize outerSize = (jsize) length1D; /* EDIT thanks to John Bickers */
        jclass class = (*env)->FindClass(env, "[D"); /* EDIT thanks to Nam San */
        jobjectArray outer = (*env)->NewObjectArray(env, outerSize, class, 0);
        jsize i;
        for (i = 0; i < outerSize; i++) {
            jsize innerSize = (jsize) length2D[i]; /* EDIT thanks to John Bickers */
            jdoubleArray inner = (*env)->NewDoubleArray(env, innerSize);
            (*env)->SetDoubleArrayRegion(env, inner, 0, innerSize, data[i]);
            (*env)->SetObjectArrayElement(env, outer, i, inner);
            (*env)->DeleteLocalRef(env, inner); /* EDIT thanks to Tom Blodget */
        }
        return outer;
    }

这就是名为'getLength'的宏:

#define getLength(x)  (sizeof(x) / sizeof(x[0]))

当我运行它时会创建一个mindump (我无法理解):

我是JNI和C编程的新手,所以请详细解释究竟是什么错误以及如何修复它。

提前致谢!

更新我发现错误不是代码本身,更多是关于我试图转换的数组。 事实证明,数组中的一个元素包含的元素比其他元素多。 我试图在图书馆matio的帮助下从4级matlab文件中读取。 也许错误位于那里? 我会把一切都放在下面:

#include <jni.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <matio.h>
#include "ReadMatFile.h"

//macros
#define getLength(x)  (sizeof(x) / sizeof(x[0]))

//variables
double *dataMatrix[4];
int innerSize[getLength(dataMatrix)];

//functions
jobjectArray convertToArray(JNIEnv *env, double **data, int length1D,
        int *length2D);

JNIEXPORT jobjectArray JNICALL Java_ReadMatFile_readMatFile(JNIEnv *env,
        jobject object, jstring str) {
    const char *fileName = (*env)->GetStringUTFChars(env, str, 0);
    mat_t *matfp;
    matvar_t *matvar;
    printf("%s\n", fileName);
    matfp = Mat_Open(fileName, MAT_ACC_RDONLY | MAT_FT_MAT4);
    if ( NULL == matfp) {
        fprintf(stderr, "Error opening MAT file %s\n", fileName);
        return NULL;
    }
    int i = 0;
    while ( NULL != (matvar = Mat_VarReadNext(matfp))) {
        double *data = (double*) (matvar->data);
        dataMatrix[i] = data;
        innerSize[i] = (int) matvar->nbytes / matvar->data_size;
        Mat_VarFree(matvar);
        matvar = NULL;
        i++;
    }
    Mat_Close(matfp);
    (*env)->ReleaseStringUTFChars(env, str, fileName);
    int outerSize = (int) getLength(dataMatrix);
    return convertToArray(env, dataMatrix, outerSize, innerSize);
}

jobjectArray convertToArray(JNIEnv *env, double **data, int length1D,
        int *length2D) {
    jsize outerSize = (jsize) length1D;
    jclass class = (*env)->FindClass(env, "[D");
    jobjectArray outer = (*env)->NewObjectArray(env, outerSize, class, 0);
    jsize i;
    for (i = 0; i < outerSize; i++) {
        jsize innerSize = (jsize) length2D[i];
        jdoubleArray inner = (*env)->NewDoubleArray(env, innerSize);
        (*env)->SetDoubleArrayRegion(env, inner, 0, innerSize, data[i]);
        (*env)->SetObjectArrayElement(env, outer, i, inner);
        (*env)->DeleteLocalRef(env, inner);
    }
    return outer;
}

另一个更新

似乎错误在数组的第一个元素中。 我确定这一点,因为如果我在另一个数组上运行代码的值较少,那么它的工作原理非常好。 但是,如果我尝试运行此代码,我只返回第一个数组,它会创建一个minidump:

#include <jni.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <matio.h>
#include "ReadMatFile.h"

//macros
#define getLength(x)  (sizeof(x) / sizeof(x[0]))

//variables
double *dataMatrix[4];
int innerSize[getLength(dataMatrix)];

//functions
jobjectArray convertTo1DArray(JNIEnv *env, double *data, int length);

JNIEXPORT jdoubleArray JNICALL Java_ReadMatFile_readMatFile(JNIEnv *env,
        jobject object, jstring str) {
    const char *fileName = (*env)->GetStringUTFChars(env, str, 0);
    mat_t *matfp;
    matvar_t *matvar;
    matfp = Mat_Open(fileName, MAT_ACC_RDONLY | MAT_FT_MAT4);
    if ( NULL == matfp) {
        fprintf(stderr, "Error opening MAT file %s\n", fileName);
        return NULL;
    }
    int i = 0;
    while ( NULL != (matvar = Mat_VarReadNext(matfp))) {
        double *data = (double*) (matvar->data);
        dataMatrix[i] = data;
        innerSize[i] = (int) matvar->nbytes / matvar->data_size;
        Mat_VarFree(matvar);
        matvar = NULL;
        i++;
    }
    Mat_Close(matfp);
    (*env)->ReleaseStringUTFChars(env, str, fileName);
    return convertTo1DArray(env, dataMatrix[1], innerSize[1]);
}

jobjectArray convertTo1DArray(JNIEnv *env, double *data, int length) {
    jdoubleArray arr = (*env)->NewDoubleArray(env, (jsize) length);
    (*env)->SetDoubleArrayRegion(env, arr, 0, (jsize) length, data);
    (*env)->DeleteLocalRef(env, arr);
    return arr;
}

但是,如果我在数组中的下一个元素(即索引1而不是索引0)上运行代码,则它不会创建minidump,也不会返回数组。 它创建minidump的原因很可能是因为第一个数组包含从level-4 matlab文件中检索的1000004个double值。 所以大家都知道这个问题已经解决了。 但不幸的是,我描述的问题仍然存在(即它仍然创建了minidump)。 所以感谢大家,我可能会发布另一个关于巨大数组问题的问题。

一个大问题是getLength(数据)没有返回你期望的结果。 因为函数被赋予指向double的指针,sizeof(x)是指向指针的指针的大小,而sizeof(x [0])是指向double的指针的大小。 结果很可能是1.在函数内部,您的代码无法分辨数据矩阵的维度。

您应该更改函数以使数据只是一个double *,再添加两个参数来给出两个数组维度innerSize和outerSize,并在调用SetDoubleArrayRegion()时执行一些算法以将索引转换为数据。

这是如何使用JNI返回2D长数组的重复,除了您需要2D双数组而不是2D长数组。 对于2D双数组,您的FindClass()方法需要找到"[D"而不是"java/lang/Double"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM