2012-09-30 85 views
2

Java代碼:JNI崩潰:S

package library; 

import java.nio.ByteBuffer; 

public class Library 
{  
    static{System.loadLibrary("TestDLL");} 

    native static void GetGLBuffer(ByteBuffer Buffer, int Width, int Height, int Size); 

    public static void main(String[] args) { 

     ByteBuffer B = ByteBuffer.allocateDirect(5); 
     byte[] C = {'H', 'E', 'R', 'E', '\0'}; 
     B.put(C); 
     GetGLBuffer(B, 0, 0, 4); 
     System.out.println((char)B.get(0)); 
    } 
} 

C++代碼:

JNIEXPORT void JNICALL Java_library_Library_GetGLBuffer(JNIEnv *env, jclass cls, jobject buffer, jint Width, jint Height, jint Size) 
{ 
    unsigned char* Buff = (unsigned char*)env->GetDirectBufferAddress(buffer); 
    //*Buff = 'A'; Crashes it. 
    //Buff[0] = 'A'; Crashes it. 
    //std::cout<<Buff[0]; Prints fine but crashes when this function ends. 
} 

如果我什麼都不做,它完美的罰款。另外,如果我在上面的函數中聲明瞭變量,它會崩潰。

我該如何解決?我做錯了什麼?

它打印出這個文件:http://pastebin.com/Mz76Bk8G

回答

0

我只想說,我解決它。我必須進入我的JNI文件夾,將JDK 7的JNI.h和JNI_MD.h複製到我的C++項目文件夾中,將其作爲文件包含並使用.def文件進行導出。

如果不執行上述所有步驟,就會導致JVM崩潰。現在我不知道爲什麼,但我很高興它的工作原理。我發佈這個讓其他有相同問題的人修復它。

Thanx的意見傢伙。很難弄清楚什麼是錯的。希望此評論有助於其他人。

+0

你不應該複製文件;你應該#從他們已經存在的地方包括他們。您不應該需要帶JNI的.def文件。 – EJP

+0

沒有.def時不起作用。我不知道爲什麼。 我得到: 異常線程 「main」 java.lang.UnsatisfiedLinkError中:Library.GetGLBuffer;在Library.GetGLBuffer(本機方法) 在Library.main(圖書館V (L 的Java/NIO /字節緩衝區)。 java:21) 現在,如果我使用.def文件,它工作得很好。 – Brandon

0

問題是你沒有傳遞一個字節數組到你的C函數,而是一個ByteBuffer對象。要在緩衝區中設置值,您需要調用緩衝區對象上的方法,其中C表示查詢對象的類,查詢類的正確方法,然後調用方法。

例如,如果你想要做調用的put(INT指數,字節B)方法字節緩衝區對象上的等價,你需要做這樣的事情在你的C代碼:

jclass cls = (*env)->GetObjectClass(env, objID); 
jmethodId mid = (*env)->GetMethodID(env, cls, "put","(IB)V"); 
if(mid == 0) return; 
(*env)->CallVoidMethod(env, objID, mid, 0, 'A'); 
+0

他正在使用直接字節緩衝區;他正在調用正確的方法來獲取直接緩衝區地址;他然後直接使用直接緩衝區地址。他的代碼是正確的,應該可以工作。 – EJP

+0

由於我已經對JNI做了任何事情,這絕對是太久了 - 完全忘記了使用直接字節緩衝區。感謝您的更正! –