2013-11-01 74 views
1

我有JNI的問題,再次...與DLL文件的JNI問題

這次我的代碼工作...但是...不正確的所有PC上。

我:

  1. Jar文件 - >我的前衛
  2. dll文件 - >與本地方法
  3. 另一dll文件 - >與其他功能。

在我的電腦上所有這些文件都在一個文件夾中。

文件代碼(的.java):

// loading library 
    try { 
     Runtime.getRuntime().loadLibrary("E140tests"); 
     setText("Library E140tests.dll was loaded correctly."); 
    } catch (UnsatisfiedLinkError ex) { 
     // try load with absolute path 
     setText("Error: E140tests.dll wasn't loaded!"); 
     setErrorFlag(true); 
    } 

E140tests.dll - >第二文件(在MSVS compileted)

#include "jni.h" 
#include "jni_md.h" 
#include "Lusbapi.h" 
#include "LusbapiTypes.h" 
#include "JNITEST2.h" 

#ifdef __cplusplus 
extern "C" { 
#endif 

/* 
* Class:  JNITEST2 
* Method: ADCinit 
* Signature: (LJNITEST2;)V 
*/ 
JNIEXPORT void JNICALL Java_JNITEST2_ADCinit 
    (JNIEnv* env, jobject, jobject obj) { 
    ... 

lusbapi.dll - >第三個文件,與另一種功能。

#ifndef __LusbapiH__ 
#define __LusbapiH__ 

// -------------------------------------------------------------------------- 
// ---------------------------- COMMON PART --------------------------------- 
// -------------------------------------------------------------------------- 
#include <windows.h> 
#include "LusbapiTypes.h" 

如果我把我的文件放在system32中,所有的都可以。

但是。在另一臺PC(XP,7)我的代碼不起作用!無所謂:如果文件(+ dll)在一個文件夾中,或者dll文件在system32中 - >代碼找不到它們。

我想,這個問題是在運行時庫(MSVS),但德恩我安裝的話,什麼都沒有改變......

(我的電腦上是IntelijIDEA,MSVS,jdk7.xx - >所有作品。我測試了另一臺PC上的prog(安裝了MSVS) - >並且都運行正常,但在另一臺PC上沒有找到(並且安裝了Runtime Libraries))。

我會等待救援)

+1

您是否嘗試使用[Dependency Walker](http://www.dependencywalker.com)檢查依賴關係? – dnk

+0

'錯誤:未找到至少一個必需的隱式或轉發依賴項。 錯誤:找到了具有不同CPU類型的模塊。「在計算機上不起作用... –

+0

系統的架構不起作用以及用於編譯的系統架構是什麼? –

回答

1

不幸的是,當你編譯.DLL,它僅與匹配架構的系統兼容。 32位.DLL在32位機器上的工作,對於64位也是如此。有一些策略可以解決這個問題(購買visual studio的許可證會爲您提供允許這樣做的工具,並且會生成特定於平臺的.dll),但這意味着您必須將相應的.DLL與任何版本的程序捆綁在一起正在測試。這就是爲什麼網站上大多數時候會問你是否有32位或64位機器。

這也是java很好的主要原因之一,因爲它是'平臺獨立'(我使用這個術語是鬆散的,因爲其他的東西可能會影響它,使它不真實)。

無論哪種方式,只要添加JNI調用,就會添加一大堆依賴項,這使得分發軟件有點困難。

+0

我不確定。我的朋友有x64系統,並且所有的作品都是正確的!.. 但是在另一臺PC上(使用x64) - >不是 –

+0

如果是這種情況,那麼它可能是偶然發生在他的而不是另一臺上的。一般來說,.DLL絕對是平臺特定的,除非我知道兩個系統的確切規格,否則很難指出兩個平臺之間的確切區別,即使如此,.Dll的內容也可能會有所作爲。 – WillBD

+1

@AndrewEvt如果它在你的朋友的64位機器上工作,他應該已經安裝了32位Java。 –

0

您必須在兩種體系結構中編譯DLL。對於編譯,您可以使用您的64位系統並使用這些命令進行編譯。

對於64位(GCC)

gcc -o E140Tests64.dll -shared -IC:\....\include sourcefile.c 

對於32位(GCC)

gcc -o E140Tests.dll -shared -IC:\....\include sourcefile.c 

希望這有助於。

0

如果您打算分發您的應用程序,則需要構建DLL的32位和64位版本。然後使用以下技術來加載正確的DLL,而不考慮您的客戶JVM拱。將32或64(MyJniDLL32.dll & MyJniDLL64.dll)附加到生成的輸出文件中。

String archDataModel = System.getProperty("sun.arch.data.model"); 
System.loadLibrary(libraryName+archDataModel); 

DLL的拱(32比64),必須在JVM ACH(32比64),而不是OS拱相匹配。如果您在64位操作系統上運行32位JVM,則您的Java代碼必須能夠訪問32位DLL。