2011-08-07 142 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 。