2011-07-07 54 views
2

我想創建一個可從Java調用的C動態庫。我Cygwin下編譯一個DLL,使用SWIG與下面的Makefile生成JNI:調用由SWIG生成的JNI的UnsatisfiedLinkError?

CC= gcc -mno-cygwin 
SWIG= /cygdrive/c/Documents\ and\ Settings/student/Desktop/swigwin-2.0.4/swig.exe -java 
INCLUDE1= -I/cygdrive/c/Program\ Files/Java/jdk1.6.0_25/include 
INCLUDE2= -I/cygdrive/c/Program\ Files/Java/jdk1.6.0_25/include/win32 

utilities: 
    ${SWIG} utilities.i 
    ${CC} -c utilities.c utilities_wrap.c ${INCLUDE1} ${INCLUDE2} 
    ${CC} -shared utilities.o utilities_wrap.o -Wl,--add-stdcall-alias -o utilities.dll 

以下是SWIG接口文件的內容utilities.i

/* utilities.i */ 
%module utilities 
%{ 
#include "driver.h" 
%} 

extern int get_3711a_fd(char * device); 
/* Other prototypes omitted for brevity */ 

我已經驗證了這些方法正在從DLL中正確導出,並且將utilities.dll置於以下兩者中:

  1. C:\ Program Files文件\的Java \ jdk1.6.0_25 \ BIN
  2. C:\ Program Files文件\的Java \ jdk1.6.0_25 \ jre的\ BIN

我用System.load(libraryPath)從路徑1加載上面的,路徑中包含庫文件名,並在該調用上捕獲任何SecurityExceptionUnsatisfiedLinkError

的庫加載沒有任何異常,但在調用庫失敗,出現以下:

Exception in thread "main" java.lang.UnsatisfiedLinkError: 
invokeoncomport.utilitiesJNI.get_3711a_fd(Ljava/lang/String;)I 
    at invokeoncomport.utilitiesJNI.get_3711a_fd(Native Method) 
    at invokeoncomport.utilities.get_3711a_fd(utilities.java:14) 
    at invokeoncomport.Main.main(Main.java:41) 
+0

是utilities_wrap.c SWIG生成的包裝代碼? –

+0

是的,它似乎有必要的出口;例如。 'SWIGEXPORT jint JNICALL Java_utilitiesJNI_get_13711a_1fd(...)' – Rob

回答

3

我發現this section of the SWIG documentation,它說:

的的packageName和MODULENAME必須 當然是正確的否則,當JVM動態加載JNI函數時,您將收到 鏈接器錯誤。

看過utilities_wrap.c後,我看到我生成的JNI方法定義沒有包含一個包名。爲了解決這個問題,我加入了SWIG -package command-line option我的makefile文件的第一行:

swig.exe -java -package invokeoncomport utilities.i 

我的JNI方法的定義現在看起來像下面,和我的鏈接錯誤是固定的!

SWIGEXPORT jint JNICALL Java_invokeoncomport_utilitiesJNI_set_13711a_on(...)