C:将2D双阵列到Java 2D双阵列 [英] C: Converting a 2D double array to a java 2D double array

查看:122
本文介绍了C:将2D双阵列到Java 2D双阵列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图运行在Java本机方法,然后接收二维double数组,我可以在java中使用。我已经成功地操纵在C中的数据,但现在我需要把它送回来到Java。我将如何转换一个二维double数组在C二维double数组在Java?

I'm trying to run a native method in java and then receiving a 2D double array that I can use in java. I've successfully manipulated the data in C but now I need to send it back to java. How would I convert a 2D double array in C to a 2D double array in java?

我试过这个简单的code我想到了,但遗憾的是不工作:

I've tried this simple code I came up with but it unfortunately doesn't work:

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'的宏:

And this is the macro called 'getLength':

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

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

When I run this it creates a mindump (which I can't understand):

我是新来的JNI和C编程两个,所以请解释相当详细的到底什么是错的,我会怎样解决它。

I'm new to both the JNI and C programming, so please explain rather detailed what exactly is wrong and how I would fix it.

在此先感谢!

更新
我发现错误不是关于code本身,更多的数组,我尝试转换。事实证明,在阵列中的一个元素包含很多比其他的多个元件。我试图从库matio帮助一个4级MATLAB文件中读取。也许错误是设在那里?我要把一切如下:

UPDATE I found out that the error is not about the code itself, more about the array I'm trying to convert. It turns out that one element in the array contains alot more elements than the other ones. I'm trying to read from a level-4 matlab file with help of the library matio. Maybe the error is located there? I'll put everything below:

#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;
}

另一个更新

好像误差是在该阵列的第一个元素。我相信这一点,因为如果我跑在另一个数组code用更少的价值观它完美的罚款。但是,如果我尝试运行此code,其中我只返回它创建一个小型转储的第一个数组:

It seems like the error is in the first element of the array. I'm sure about this because if I run the code on another array with less values it works perfectly fine. But if I try to run this code where I'm ONLY returning the first array it creates a 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;
}

但是,如果我运行下一个元素的code数组中(即而不是指数1指数0)它不会创建转储也不无法返回数组。因为第一个数组包含从4级MATLAB文件中检索1000004双重价值它创建一个转储的原因是最有可能的。所以这个问题是已经解决了,感谢大家。但unfortunently我所描述的问题仍然存在(即它仍然创建转储)。所以感谢大家,我可能会发布有关巨大的数组问题,另外一个问题。

However, if I run the code on the next element in the array (i.e index 1 instead of index 0) it doesn't create a minidump nor does it fail to return the array. The reason it creates a minidump is most likely because the first array contains 1000004 double values retrieved from a level-4 matlab file. So this question is already solved, thanks to everyone. But unfortunently the problem I described still remains (i.e it still creates the minidump). So thanks everyone, I'll probably post another question concerning the huge array problem..

推荐答案

的一个大问题是,的getLength(数据)没有返回你所期望的。因为该功能被赋予一个指针指向一个双,sizeof的(x)是一个指针的指针的大小,和sizeof(X [0])是指向一个双重的大小。其结果很可能是1.将code有没有办法告诉哪些数据矩阵的尺寸是在函数内部。

One big problem is that getLength(data) isn't returning what you expect. Because the function is given a pointer to a pointer to a double, sizeof(x) is the size of a pointer to a pointer, and sizeof(x[0]) is the size of a pointer to a double. The result is most likely 1. Inside the function your code has no way to tell what the dimensions of the data matrix are.

您或许应该改变功能,使数据仅仅是一个双*,增加两个参数来为这两个数组维度,innerSize和outerSize,并做一些算法来获取索引数据,当你调用SetDoubleArrayRegion()。

You should probably change the function so that data is just a double *, add two more parameters to give the two array dimensions, innerSize and outerSize, and do some arithmetic to get the index into data when you call SetDoubleArrayRegion().

这篇关于C:将2D双阵列到Java 2D双阵列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆