由SWIG生成的JNI调用UnsatisfiedLinkError?

3
我正在尝试创建一个可从Java调用的C动态库。我已经在Cygwin下编译了一个DLL,并使用SWIG生成JNI,以下是使用的makefile:
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)

utilities_wrap.c 是由 SWIG 生成的包装器代码吗? - Andy Thomas
是的,它似乎具有必要的导出功能;例如:SWIGEXPORT jint JNICALL Java_utilitiesJNI_get_13711a_1fd(...) - Rob
1个回答

6
我找到了SWIG文档中的这一部分链接,其中提到:
引用:

当JVM动态加载JNI函数时,packageName和moduleName必须正确,否则您将会遇到链接器错误。

在查看utilities_wrap.c后,我发现生成的JNI方法定义没有包名。为了解决这个问题,我在我的makefile的第一行添加了SWIG的-package命令行选项
swig.exe -java -package invokeoncomport utilities.i

我的JNI方法定义现在看起来像以下内容,我的链接错误已经解决了!

SWIGEXPORT jint JNICALL Java_invokeoncomport_utilitiesJNI_set_13711a_on(...)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接