2014-04-04 140 views
0

我正在從一個需要從dll文件調用某些方法的項目中工作。 這兩個DLL是JNI使用本機方法

  • EasySign.dll
  • EasySignJNI

EasySignJNI取決於EasySign。

我寫的類加載EasySignJNI如下:

package easysign; 


class EasySign { 

    EasySign(){} 

    public native String EasyHashFile(String filename); 
    public native int EasySign(String pkcs11_driver,String pin, int type, String file_data, int out_format, String signed_file, String cert_out, int cert_format); 
    public native int EasyVerify(String cert_user, String file_data, String signed_file, String crl_file, String ca_file, String out_document); 


    static { 
     System.loadLibrary("EasySignJNI"); 
    } 
} 

現在我把這些方法從我的主要方法是這樣的:

public class Test { 
    public static void main(String[] args) throws IOException{ 
      EasySign es = new EasySign(); 
      System.out.println("EasyHashFile : " + es.EasyHashFile("test.txt")); 
     } 
    } 

什麼我在-Djava.library.path指定?只有我的EasySignJNI.dll所在的路徑?用這種方法可以調用本地方法嗎? 我使用NetBeans來實現完整性。

編輯: 我注意到,第三方dll提供給我(特別是JNI dll)沒有任何包定義方法名稱,所以我不得不把類加載到默認包的類。有沒有辦法只改變dll方法名稱,包括我自己的包名?

編輯2: 我的意思是EasySign.dll和EasySignJNI.dll都是我自己提供的,我無法修改它們(我沒有源代碼)。 EasySignJNI是JNI部分,但檢查它我已經注意到方法標誌的形式爲:_java_EasySign_MethodName。當我從我的Easysign類加載Java中的dll(該類必須位於「mypackage」包中)時,我收到jni unsatisfiedlinkerror,因爲如果我理解正確,我將調用「_java_mypackage_EasySign_MethodName」方法,即符號是不同於dll的。因此,使其工作的唯一方法是重寫JNI部分並將其構建爲具有JNI方法的正確符號?

回答

0

我必須在-Djava.library.path中指定什麼?只有我的EasySignJNI.dll所在的路徑?

正確,操作系統將爲您找到相關的EasySign.dll,只要它在操作系統預期的位置可用即可。

可以用這種方式調用native方法嗎?我使用NetBeans來實現完整性。

我通讀了你的編輯,你已經成功地失去了我。你指的是什麼默認包? (請記住,我們中沒有人知道EasySign.dll是什麼)所以,我將提供一些關於我如何處理您最初描述的內容的信息,並希望這會對您有所幫助。

如果您擁有src,請首先編譯EasySign。不建立一個DLL或共享對象,而是建立一個靜態庫。如果您沒有EasySign的src代碼或者預建的靜態庫,那麼您將被困在dll中並繼續下一步。

現在您已準備好編譯jni部分。所有的JNI C代碼都應該基本上將Java輸入/輸出轉換爲它們的JVM/Native類型,並在DLL庫中調用適當的函數。您希望儘可能保持這一層次,並儘可能簡化和簡單,因爲調試非常困難。您的C++軟件包名稱在這裏並不重要,您可以使用您想要的Java類的軟件包名稱。你應該能夠編譯JNI代碼,最好是靜態鏈接到EasySign.dll文件,所以你不必擔心分發它。如果您必須動態鏈接,請確保EasySign.dll安裝到位於DLL PATH/LDPATH上的位置,因爲操作系統在JVM加載JNI DLL後需要立即找到並加載該文件。

在這一點上,你應該能夠在你的JNI DLL的路徑上指向-Djava.library.path,並且所有的都應該工作。

+1

非常感謝您的回覆,感謝您的支持!我編輯了這個問題,試圖讓它更加清晰! – Dan

+0

感謝您的更新!這確實很明顯!如果EasySignJNI提供給您,它們還必須爲您提供包含它們用於構建JNI庫的本機方法聲明的JAR。不幸的是,在編譯庫之後,你不能修改本地方法簽名。所以要回答你的問題;是的,您必須重新編譯JNI部分以更改軟件包名稱。 –