我正在尝试构建一个通过JNI使用现有本机库的Java程序。本机项目有两个组件,每个组件都构建一个共享库:
core.lib
和core.dll
application.lib
和application.dll
使用SWIG,我创建了一个application_wrap.c
文件和相应的Java文件,以便我可以使用JNI访问本机库。
我想要做的是构建一个包含此application_jni.dll
文件的新共享库(让我们称之为application_wrap.c
),以便我可以在我的Java程序中加载它:
System.loadLibrary("application_jni");
不幸的是,我似乎无法弄清楚如何在Windows上使用Visual Studio编译器执行此操作。这是我尝试过的:
首先,编译SWIG生成的application_wrap.c
文件。这会产生application_wrap.obj
,似乎工作正常。
cl /I "path/to/core/headers" /I "path/to/application/headers" -c application_wrap.c
接下来,将application_wrap.obj
与现有共享库链接以创建新的共享库:
link /dll /out:application_jni.dll application_wrap.obj core.lib application.lib
这会导致大量错误,如下所示:
application_wrap.obj : error LNK2019: unresolved external symbol __imp__function_in_core referenced in function_in_application_wrap
知道可能导致这些错误的原因是什么?我没有很多在Windows上编译的经验,所以如果发现我在编译或链接阶段遗漏了一些标志(甚至误解了dll的工作方式),我也不会感到惊讶。
运行
dumpbin /exports core.lib
表明错误消息提到的所有函数实际上都是由核心共享库导出的。
在Pavel的建议中,我写了一个简单的C程序,看看它是否会链接。我使用了与上面相同的编译和链接命令,并遇到了同样的错误。
C程序test.c
:
#include "application.h"
int main() {
function_in_application();
}
错误:
test.obj : error LNK2019: unresolved external symbol __imp__function_in_application referenced in function _main
答案 0 :(得分:1)
库无法链接,因为core.dll
和application.dll
编译为64位,cl.exe
的默认目标是32位。链接器失败,因为我试图将32位obj
文件链接到两个64位dll's
。编译64位的所有内容解决了这个问题。
cl.exe
脚本(例如“amd64”),使vcvarsall.bat
目标位为64位。可以找到更深入的说明here。Visual Studio Express 2010
的默认版本不会安装64位编译器。您可能需要再次运行setup.exe
并检查相应的自定义安装选项以进行安装。Visual Studio Express 2012
的默认版本附带64位编译器。我卸载了2010版本,安装了2012版本,之后没有任何问题。