Собственный метод JNI, вызывающий сбой виртуальной машины - PullRequest
0 голосов
/ 08 августа 2011

Я реализую метод Java как нативный в C ++

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 ]

2 голосов
/ 08 августа 2011

Ваш текущий код, когда я пишу это:

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 не является ассоциативным массивом;это обычный непрерывный массив.Следовательно, вам нужно либо изменить его размер заранее, либо использовать метод push_back для добавления новых элементов.Вы можете указать размер как этот:

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

Cheers & hth.,

0 голосов
/ 11 августа 2011

Вы можете попробовать использовать опцию Java VM -Xcheck: jni.Подробности можно найти по адресу www.oracle.com / technetwork / java / javase / clopts-139448.html # gbmtq .

0 голосов
/ 08 августа 2011

У меня есть сомнения относительно того, можете ли вы вернуть int [] в виде массива объектов. В частности, линия env->GetObjectClass(jResults) кажется мне подозрительной. Эта строка пытается получить класс для int [], который, насколько мне известно, не существует. Я предлагаю либо вернуть Integer [], и таким образом получить класс с помощью env-> GetObjectClass ("java / lang / Integer), либо изменить сигнатуру метода на jintArray. Насколько я знаю, jintArray! = JobjectArray .

0 голосов
/ 08 августа 2011

Вы никогда не инициализируете переменную result, поэтому ваш код в конечном итоге пытается прочитать с адреса мусора, а затем пытается освободить указатели, которые он прочитал с адреса мусора.

(О, не важно, там был скрытый код ...)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...