【问题标题】:Name mismatch when using Fortran shared library使用 Fortran 共享库时名称不匹配
【发布时间】:2018-10-03 12:27:18
【问题描述】:

我成功地使用 IFORT 编译了一个共享库,其中包含一些由 Visual Studio C 编译的 .obj 文件(即依赖项)。

当尝试在 Fortran 程序中使用此共享库时,它会显示 Example.obj : error LNK2019: unresolved external symbol TEST_mp_EXECUTE referenced in function MAIN__ 失败。

当我使用工具dumpbin.exe 时,我可以看到函数execute 在共享库中。知道为什么名称不匹配会导致 Fortran 程序的编译失败吗?

文件Test.c的内容:

__declspec(dllexport) int execute(void);

int execute(void)
{
    return 2 + 3;
}

文件Test.c用Microsoft Visual Studio C成功编译如下(结果是一个名为Test.obj的目标文件):

cl.exe Test.c /FoTest.obj

文件Test.f90的内容:

MODULE Test

    USE, INTRINSIC :: iso_c_binding, ONLY: c_int
    IMPLICIT NONE

    INTERFACE

        INTEGER(c_int) FUNCTION execute() BIND(C, name = "execute")
            USE, INTRINSIC :: iso_c_binding, ONLY: c_int
        END FUNCTION

    END INTERFACE

END MODULE

使用 IFORT 成功编译的文件 Test.f90 如下(结果是一个名为 Test_dll.dll 的共享库及其名为 Test_dll.lib 的头文件,以及一个名为 test.mod 的 Fortran 模块文件):

ifort.exe Test.obj /Qm64 /LD /FeTest_dll.dll

文件Example.f90的内容:

PROGRAM Example

    USE test

    state = execute()

END PROGRAM

现在,当尝试将文件 Example.f90 编译为 ifort.exe Example.f90 Test_dll.lib 时,它会失败说 Example.obj : error LNK2019: unresolved external symbol TEST_mp_EXECUTE referenced in function MAIN__。知道发生了什么吗?

【问题讨论】:

  • 是的,我们需要更多详细信息,但请注意 test_execute 不是 TEST_mp_EXECUTE。后者应该是模块test 中的过程execute,而不是称为test_execute 的过程。
  • @francescalus:你是对的;我已经编辑了问题以反映您的评论,但也因为这是现实中发生的事情(不知何故,我在原始问题中错误地复制并粘贴了它)。
  • 但我们仍然需要minimal reproducible example。仅仅改变函数的名字是不够的。 MCVE 包括用于编译的命令和我们必须使用的任何其他必要配置。
  • @VladimirF:我添加了包含 MCVE 的问题。

标签: c visual-studio fortran intel-fortran


【解决方案1】:

请注意,您有两个可编译为 test.obj 的源 - Fortran 和 C。此外,您显示的 cl 命令会尝试生成可执行文件。正确的做法如下:

cl /c /MD /Foctest.obj test.c
ifort /dll test.f90 ctest.obj
ifort example.f90 test.lib

我在 C 编译中添加了 /MD 以获得一组兼容的运行时库。这会生成没有错误的可执行文件。

【讨论】:

  • 谢谢;有效!我需要包含DEC$ ATTRIBUTES DLLEXPORT :: execute(在文件Test.f90 中)才能正确使用共享库。现在,我正在尝试构建一个静态库,但是在使用它时它会说 Example.obj : error LNK2019: unresolved external symbol TEST_mp_EXECUTE referenced in function MAIN__ 失败(尽管现在有 !DEC$ ... 声明)。你知道发生了什么吗?
  • 在 Fortran 源代码中添加执行的 DLLEXPORT 是不正确的,因为执行是一个 C 例程并且您已经从 C 中导出了它。这对静态库没有任何作用。我怀疑原因和我之前写的一样——覆盖目标文件。也许您现在可以向我们展示您现在使用的源和命令是什么?
  • 当然@Steve。用于构建静态库的命令是lib.exe ctest.obj test.obj /OUT:test_static.lib,运行成功。用于构建使用静态库 test_static.lib 的 Fortran 程序 (example.f90) 的命令是 ifort.exe example.f90 test_static.lib,但由于上述错误而失败。
猜你喜欢
  • 2018-10-23
  • 1970-01-01
  • 2011-07-19
  • 2013-05-21
  • 2014-09-22
  • 2018-10-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多