2010-04-29 37 views
1

我使用JNI Invocation API編碼了一些東西。一個C程序啓動一個JVM並調用它。 JNIenv指針對於C文件是全局的。我有許多C函數需要對給定的工作類執行相同的操作。所以我編寫了helper函數,它接受jobject並處理它,返回所需的數據(一個C數據類型,例如一個int狀態值)。編寫C幫助函數並將作業作爲參數傳遞給它們是否安全?在JNI Invocation API中工作時安全地將對象傳遞給C函數?

即(一個簡單的例子 - 用來說明問題):

int getStatusValue(jobject jStatus) 
{ 
    return (*jenv)->CallIntMethod(jenv,jStatus,statusMethod); 
} 

int function1() 
{ 
    int status; 
    jobject aObj = (*jenv)->NewObject 
    (jenv, 
    aDefinedClass, 
    aDefinedCtor); 

    jobject j = (*jenv)->CallObjectMethod 
    (jenv, 
    aObj, 
    aDefinedObjGetMethod) 

    status = getStatusValue(j); 

    (*jenv)->DeleteLocalRef(jenv,aObj); 
    (*jenv)->DeleteLocalRef(jenv,j); 

    return status; 

} 

感謝。

回答

0

我不和JNI的細節的人,但一旦件事我注意到的是:

return (*jenv)->CallIntMethod(jenv,jStatus,statusMethod); 

看起來像官方JNI代碼,它走的是一條jobect作爲參數。如果它適用於JNI,那麼沒有理由不能爲你的代碼工作。

0

所有jni對象在本機方法返回前都有效。只要你不存儲兩個jni調用之間的非全局jni對象,一切都應該工作。
一個JNI函數的調用應該像這樣工作:

  1. Java函數調用
  2. 創建本地局部引用
  3. 調用本地函數
  4. 做你的東西
  5. 退出本地函數
  6. 釋放現有的本地參考文獻
  7. 返回到java

第4步可以包含任何代碼,本地引用保持有效,直到第6步如果不釋放之前。
如果你想在兩個調用本地java函數之間的c端存儲jni對象,你必須創建全局引用並在以後發佈它們。由於垃圾收集器無法釋放相關的Java對象,因此不釋放全局引用會導致內存泄漏。

+0

我使用JNI調用API從C的邏輯流程是這樣的: 0.啓動了JVM中C. 1.從C調用到Java 2.手柄結果從Java返回。 3.發佈本地參考。 4.關閉JVM。 步驟1-3可能會在JVM啓動和關閉之間發生N次。我做了一些測試,看起來沒問題。這些文檔讓我擔心傳遞這些本地引用...... – bubbadoughball 2010-04-30 04:59:55