0

背景

我正在尝试构建一个通过 JNI 使用现有本机库的 Java 程序。本机项目有两个组件,每个组件都构建一个共享库:

  1. 构建core.lib和构建的核心组件core.dll
  2. 一个依赖于核心组件的应用程序组件,并构建application.libapplication.dll

使用 SWIG,我创建了一个application_wrap.c文件和相应的 Java 文件,以便我可以使用 JNI 访问本机库。

我想做的是构建一个application_jni.dll包含这个application_wrap.c文件的新共享库(让我们称之为),这样我就可以像这样在我的 Java 程序中加载它:

System.loadLibrary("application_jni");

问题

不幸的是,我似乎无法弄清楚如何使用 Visual Studio 编译器在 Windows 上执行此操作。这是我尝试过的:

首先,编译application_wrap.cSWIG 生成的文件。这会产生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
4

1 回答 1

1

库链接失败,因为core.dll它们application.dll是为 64 位编译的,默认目标cl.exe是 32 位。链接器失败是因为我试图将一个 32 位obj文件链接到两个 64 位文件dll's。为 64 位编译所有内容解决了这个问题。

需要注意的几件事

  • 如果您安装了 64 位编译器,您可以cl.exe通过运行vcvarsall.bat带有与您的目标平台相对应的参数(例如“amd64”)的脚本来生成目标 64 位。可以在此处找到更深入的说明。
  • 默认版本默认Visual Studio Express 2010不安装 64 位编译器。您可能需要setup.exe再次运行并检查适当的自定义安装选项来安装它们。
  • 的默认版本Visual Studio Express 2012带有 64 位编译器。我卸载了2010版本,安装了2012,之后就没有问题了。
于 2013-01-16T16:23:57.087 回答