2012-11-01 54 views
3
  1. 我可以枚舉Java中的所有本機方法,那些必須是在c/C++中使用JNI實現的 ?
  2. 我可以通過 名稱枚舉本機方法嗎(可能有多個重名的同名)?
  3. 如何檢索方法簽名以便能夠生成JNI使用的方法 簽名?

有沒有辦法檢查所有原生jni方法是否已經被正確綁定,而不是試圖調用它們並得到java.lang.UnsatisfiedLinkError異常。有時方法簽名在兩邊都沒有正確更新java或c + +端,我想添加一些調試代碼來檢測這些問題並處理它們(可能通過生成適當的方法簽名並將其打印到日誌中,以便我可以輕鬆地修復碼)。JNI:如何獲得用於調試目的的方法簽名

我更喜歡JNI解決方案,但如果可以在java端的幫助下完成某些工作,那麼也可以。 如果我使用registerNatives並註冊失敗並沒有在Java中聲明則方法並打印到logcat的:

E/dalvikvm(1445): ERROR: couldn't find native method 
E/dalvikvm(1445): Requested: Lcom/bla/bla/bla/Test;.nativeTestXX:()Z 

,但我想抓住這個錯誤並處理它自己。可以做到嗎?

編輯: 在我的JNI代碼,我有註冊所有本地方法靜態nativeInit(如建議在Android JNI tips)。在這個相同的函數中,我想驗證所有本地方法是否被正確綁定。也就是說,我不需要等到一些未初始化的方法被調用並且應用程序存在。我有這樣的問題:有不同的ppl在不同的時間編寫了很多jni代碼,有些方法簡單地變得不正確,但是它們僅在一些不明確的條件下使用。對我來說,我認爲最好的辦法是檢查所有本地方法是否綁定到某個C++函數。另一個問題是,JNI代碼的一部分通過導出所有這些Long_java_names使用綁定,其中方法簽名在任何一方發生更改都無法檢測到。

+0

這就是所謂的單元測試。你編寫一個單元測試,調用應該存在的每個本地方法。你*不*編寫試圖自行調試的代碼。 – EJP

+0

[java.lang.reflect.Modifier](http://docs.oracle.com/javase/tutorial/reflect/member/methodModifiers.html)可能是你的朋友,但@EJP是非常正確的。也許你正在嘗試編寫一個自動化的單元測試,但它仍然是一個錯誤的路徑。單元測試單元測試是一個可怕的想法。 –

+0

我沒有寫自動單元測試。這只是驗證在java端聲明的所有本地方法實際上是綁定到某些函數而不是等待這些在符文時拋出的錯誤。在原始問題中查看我的編輯 – Pavel

回答

0

沒有呼叫檢查「未綁定」的本地方法。使用RegisterNatives執行顯式註冊可確保您註冊的所有方法在Java源代碼中都有匹配聲明,但無法檢查沒有實現的本機聲明方法(除調用它並捕獲異常外)。

在調用本地實現的方法的地方,如果還沒有註冊,Dalvik將搜索各種共享庫以查找匹配項。它聽起來像你想要的是一種強制搜索和檢查結果而不實際調用方法的方法。哪有這回事。

有多種方法可以靜態地或在運行時生成本地聲明方法的列表,但是您還需要一種方法來確定實現是否可用。從長遠來看,使用單元測試來鍛鍊代碼會更好。