2012-10-29 21 views
0

當我有一個通過JNI調用C++實現的一些本地方法的簡單Java類。訪問衝突((0000005))傳遞一個字符串JNI

Java代碼看起來像這樣

String in_test="./xml/input/imagen_0023.xml"; 
//String in_test="avc"; 
String out_test=acr.testString2(in_test); 
System.out.println("test: " + out_test); 

testString2的實現是一個DLL,由java程序直接調用。 testString2方法的定義如下。

JNIEXPORT jstring JNICALL Java_com_accsa_ocr_AutomaticCharacterRecognition_testString2(JNIEnv *env, jobject obj, jstring string) 
{ 
    const char *str = env->GetStringUTFChars(string, 0); 

    //std::string s=amt_test_string(str); 
    std::string s="hello: "+(std::string)str; 
    env->ReleaseStringUTFChars(string, str); 
    return env->NewStringUTF(s.c_str()); 
} 

的調用amt_test_string在別處定義(另一個DLL):

std::string AMT_EXPORT amt_test_string(std::string in) 
{ 
    std::string s="path: "+in; 
    std::cout<<s<<std::endl; 
    return s; 
} 

如果我運行它,這樣它的作品整齊,但一旦我取消 的std :: string s = amt_test_string( STR) 我得到一個訪問衝突錯誤如下:

# 
# A fatal error has been detected by the Java Runtime Environment: 
# 
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x77ae2cc7, pid=8072, tid=7328 
# 
# JRE version: 7.0_09-b05 
# Java VM: Java HotSpot(TM) Client VM (23.5-b02 mixed mode, sharing windows-x86) 
# Problematic frame: 
# C [ntdll.dll+0x52cc7] RtlFreeHeap+0xcd 

但行爲是有點飄忽不定。如果我減少輸入參數的長度,即使用

//String in_test="avc"; 

程序再次運行。從我學習的google搜索中可以看出,它們在發佈後使​​用了堆棧分配的變量,但我真的不知道如何調試。

編輯1:AMT_EXPORT宏僅用於導出符號的方便快捷:我在Windows 7 32位與Visual Studio 2010和Oracle JDK 09年7月1日

EDIT 2編譯此。請參見下面的定義:

#ifdef WIN32 
    #ifdef AMT_EXPORTS 
     #define AMT_EXPORT __declspec(dllexport) 
    #else 
     #define AMT_EXPORT __declspec(dllimport) 
    #endif 
#else 
    #define AMT_EXPORT 
#endif 
+2

什麼是'AMT_EXPORT'?它看起來像一個宏名稱。如果它評估爲&&,你就會遇到問題。 –

+0

對不起,我添加了定義 –

+0

你的DLL是否都鏈接到相同的C++運行時DLL?如果沒有,那麼你的C++幾乎肯定會崩潰,不管有沒有Java。 –

回答

0

對於調試JNI代碼,發佈在this article中的方法可能很有用(它是關於使用Netbeans和Visual Studio調試JNI)。這很簡單 - 只需啓動Java程序,然後在Visual Studio中選擇Debug - > Attach來處理並選擇運行程序的java.exe進程。

當您添加斷點來你的C++代碼,Visual Studio將打破他們。 Voila :)

1

我不認爲你應該投通過調用相應的std :: string構造const char *std::string

std::string s="hello: "+(std::string)str; 

替換。

+0

我同意你的看法,我確實嘗試過。但這不是問題的原因。 –