JNI本机方法导致VM崩溃

时间:2011-08-07 22:46:20

标签: java c++ function java-native-interface

我在C ++中实现了一个Java方法

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

有什么想法吗?

4 个答案:

答案 0 :(得分: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的各种元素。

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

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

干杯&amp;第h。,

答案 1 :(得分:0)

您永远不会初始化result变量,因此您的代码最终会尝试从垃圾地址读取,然后尝试释放已从垃圾地址读取的指针。

(哦,没关系,有隐藏的代码......)

答案 2 :(得分:0)

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

答案 3 :(得分:0)

您可以尝试使用Java VM选项-Xcheck:jni。详细信息可在www.oracle.com/technetwork/java/javase/clopts-139448.html#gbmtq找到。