【问题标题】:Errors building a DLL that depends on two other DLL's构建依赖于其他两个 DLL 的 DLL 的错误
【发布时间】:2013-01-15 22:26:15
【问题描述】:

背景

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

  1. 构建core.libcore.dll 的核心组件
  2. 依赖于核心组件的应用程序组件,构建application.libapplication.dll

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

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

System.loadLibrary("application_jni");

问题

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

首先,编译 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

【问题讨论】:

  • 您是否尝试过创建一个简单的原生 main() 来调用您的 application 的函数?那个链接吗?我没有看到您的流程有任何明显的问题,所以我正在关注 SWIG 层。
  • @Pavel Zdenek 我编写了一个简单的 C 程序来调用 application 中的函数并遇到了同样的错误。我已编辑问题以包含新信息。
  • 使用 SWIG 听起来是个好主意,直​​到你发现你现在有两个问题。编译器仍然确信这些函数是在 DLL 中定义的,而不是在静态链接库中。您需要在 SWIG 生成的代码中跟踪 __declspec(dllimport)。

标签: windows visual-c++ dll java-native-interface


【解决方案1】:

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

需要注意的几件事

  • 如果您安装了 64 位编译器,您可以通过运行 vcvarsall.bat 脚本并使用与您的目标平台相对应的参数(例如“amd64”)来使 cl.exe 成为 64 位目标。更深入的说明可以找到here
  • Visual Studio Express 2010 的默认版本默认不安装 64 位编译器。您可能需要再次运行 setup.exe 并检查相应的自定义安装选项来安装它们。
  • Visual Studio Express 2012 的默认版本确实带有 64 位编译器。我卸载了2010版本,安装了2012,之后就没有问题了。

【讨论】:

    猜你喜欢
    • 2011-01-13
    • 2010-11-11
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-09
    相关资源
    最近更新 更多