2012-03-10 64 views
0

我正在開發一個調用本機DLL庫的Java應用程序。我爲C++編寫代碼的方法,我稱之爲:JNI本機DLL不返回jobjectArray崩潰VM

JNIEXPORT jobjectArray JNICALL Java_Surf_TopSurfWrapp_computeSurfExtractDescriptor__LSurf_TopSurfVisualword_2Ljava_lang_String_2(JNIEnv *env, jclass c, jobject vw, jstring imagePath) 
{ 
c = env->GetObjectClass(vw); 
printf("start\n"); 
jobjectArray ret = (jobjectArray) env->NewObjectArray(100, c, vw); 

for (int i = 0; i < 100; i++) 
{ 
    jmethodID visualWordConstructor = env->GetMethodID(c, "<init>", "(IFFIFFFF)V"); 
    jobject element = env->NewObject(c, visualWordConstructor, 1, 1.0, 1.0, 1, 1.0, 1.0, 1.0, 1.0); 
    env->SetObjectArrayElement(ret, i, element); 
} 
    printf("end\n"); 
return ret; 
} 

我省略了一些計算,但這個問題似乎當JNI是返回jobjectArray是。 我的Java代碼:

public class Wrapp { 
    native public static TopSurfVisualword[] computeSurfExtractDescriptor(TopSurfVisualword initVW, String imagePath); 
    static { 
     System.loadLibrary("TopSurfWrapp"); 
    } 

    public static void main(String[] args) { 
    TopSurfVisualword[] d = TopSurfWrapp.computeSurfExtractDescriptor(new TopSurfVisualword(), "d:\\oil.jpg"); 
    } 
} 

我收到以下錯誤JVM:

debug: 
# 
# A fatal error has been detected by the Java Runtime Environment: 
# 
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000076d73332, pid=3384, tid=1572 
# 
# JRE version: 7.0-b147 
# Java VM: Java HotSpot(TM) 64-Bit Server VM (21.0-b17 mixed mode windows-amd64 compressed oops) 
# Problematic frame: 
# C [ntdll.dll+0x53332] 
# 
# 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: 
# D:\Programming\Visual Studio projects\GPC\TopSurfWrapp\x64\Release\hs_err_pid3384.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. 
# 
start 
end 
Java Result: 1 

因爲我得到了「開始」和「結束」的消息,我假設的問題是在返回數組。 有問題的框架似乎在ntdll.dll(這不是我的動態庫)。 請幫忙。

+1

您的代碼中沒有錯誤檢查。您可以使用本地調試器附加到java進程並檢查dll內部發生了什麼。或者至少檢查'env'方法調用的返回值並打印調試消息。 – Mersenne 2012-03-10 12:22:31

+0

返回值很好,在發佈一些我用來計算創建jobject值的資源時發生了一些問題。 – Mihai 2012-03-10 16:05:14

回答

3

我在我的系統上測試了您的示例,它運行良好。

一些提示,調試......

1)在本機代碼用printf調試運行,遵循fflush每個printf的。

printf("debug message\n"); 
fflush(stdout); 

2)檢查來自JNI函數的空返回值。

jmethodID visualWordConstructor = env->GetMethodID(c, "<init>", "(IFFIFFFF)V"); 
if(visualWordConstructor==0) { 
    // print/fflush an error message or throw an exception or both 
    // stop processing and return to java now 
} 

3)在JNI期間打印到標準輸出和異常/錯誤可能會非常棘手。 請嘗試以下操作以觀察行爲。

jclass rx = env->FindClass("java/lang/RuntimeException"); 
printf("start\n"); 
fflush(stdout); 

env->ThrowNew(rx, "thrown from native code"); 

printf("end\n"); 
fflush(stdout); 

您將首先看到「結束」,然後看到異常。
這是預料之中的,因爲在JNI期間的例外是 排隊,直到java方得到控制。

+0

感謝您的回答,您有一個觀點,我已經找到了導致EXCEPTION_ACCESS_VIOLATION錯誤的原因,並且這是一個釋放一些資源的問題,我用它來計算創建jobject的某些值。 – Mihai 2012-03-10 16:03:41