2011-08-07 125 views
0

我执行的Java方法母语C++
JNI本地方法导致VM崩溃

JNIEXPORT jobjectArray JNICALL myMethod(JNIEnv *env, jclass, //parameters){ 

    int** result = //my function to obtain a matrix n x m of integers 
    std::vector<jint> tmp; 

    //fill the vector tmp with matrix integers and deallocate the matrix 
    for (int i = 0; i < n; i++){ 
     for (int j = 0; j < m; j++){ 
      tmp[m*i + j] = result[i][j]; 
     } 
     free(result[i]); 
    } 
    free(result); 

    jintArray jResults = env->NewIntArray(tmp.size()); 
    env->SetIntArrayRegion(jResults, 0, tmp.size(), &tmp[0]); 
    return env->NewObjectArray(tmp.size(), env->GetObjectClass(jResults), 0); 
} 

它编译罚款和java成功加载DLL。但我得到这个错误在运行时:

# 
# A fatal error has been detected by the Java Runtime Environment: 
# 
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x10009a7d, pid=2264, tid=3856 
# 
# JRE version: 7.0-b147 
# Java VM: Java HotSpot(TM) Client VM (21.0-b17 mixed mode, sharing windows-x86) 
# Problematic frame: 
# C [myDLL.dll+0x9a7d] 
# 
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows 
# 
# An error report file with more information is saved as: hs_err_pid2264.log 
# 
# If you would like to submit a bug report, please visit: 
# http://bugreport.sun.com/bugreport/crash.jsp 
# The crash happened outside the Java Virtual Machine in native code. 
# See problematic frame for where to report the bug. 
# 
Java result 1 

任何想法?

+0

的功能是什么的Java的声明是它应该返回一个int [] [] (因为这是你在return语句中创建的)? –

回答

2

您当前的代码,我写这篇文章:

JNIEXPORT jobjectArray JNICALL myMethod(JNIEnv *env, jclass, //parameters){ 

    int** result = //my function to obtain a matrix n x m of integers 
    std::vector<jint> tmp; 

    //fill the vector tmp with matrix integers and deallocate the matrix 
    for (int i = 0; i < n; i++){ 
     for (int j = 0; j < m; j++){ 
      tmp[m*i + j] = result[i][j]; 
     } 
     free(result[i]); 
    } 
    free(result); 

    jintArray jResults = env->NewIntArray(tmp.size()); 
    env->SetIntArrayRegion(jResults, 0, tmp.size(), &tmp[0]); 
    return env->NewObjectArray(tmp.size(), env->GetObjectClass(jResults), 0); 
} 

在这段代码中你所访问的各种元素的零大小矢量tmp

A std::vector不是关联数组;它是一个普通的连续数组。因此,您需要预先调整大小,或使用方法添加新元素。您可以指定一个尺寸是这样的:

std::vector<jint> tmp(m*n); 

干杯&心连心,

+0

谢谢:)我是新来的C++,主要是Java开发人员。 终于现在我从java端得到一个结果,但它是空的!我认为return命令也有错误 – Oneiros

+0

自从我做了JNI之后已经过了十多年了,但是我从代码中看到的印象是'return'表达式创建了一个包含所有空值的数组,并且您可能应该而是返回'jResults'。 :-) –

+0

对于最后的评论感到抱歉,看着返回类型看起来我的印象是错误的。但不知何故,你需要将这些值传递给返回的数组对象。 –

0

你永远不会初始化result变量,所以你的代码最终试图从垃圾地址读取,然后尝试释放它从垃圾地址读取的指针。

(唉,别提了,有被隐藏的代码...)

+0

我从返回一个'int **'的函数获得该变量的值 – Oneiros

+0

在你引用的代码中没有这样的获取(啊,是否有一些有趣的东西被评论取代?那么我们应该怎样才能做到lp你?) –

+0

我用一个评论替换了该函数,因为我的问题与该函数无关。该函数只是返回一个'int **'而且它工作正常 – Oneiros

0

我有我的怀疑关于是否可以返回一个int []作为一个对象数组。特别是行env->GetObjectClass(jResults)似乎对我很可疑。这一行尝试获取int []的类,这是我所不知道的。我的建议是返回一个Integer [],并通过使用env-> GetObjectClass(“java/lang/Integer)来获得类,或者将方法签名更改为jintArray。据我所知,jintArray!= jobjectArray 。