针对静态库编译 Fortran 程序时找不到函数(在 Windows 中使用 IFORT)
Function not found when compiling a Fortran program against a static library (in Windows using IFORT)
给定以下 Fortran 模块:
MODULE Test
IMPLICIT NONE
INTERFACE
INTEGER(c_int) FUNCTION process_(script, script_size) BIND(C, name = "process")
USE, INTRINSIC :: iso_c_binding, ONLY: c_int, c_char
CHARACTER(c_char), INTENT(IN) :: script(*)
INTEGER(c_int), INTENT(IN), VALUE :: script_size
END FUNCTION
END INTERFACE
CONTAINS
FUNCTION process(script)
#ifdef SHARED_LIB
!DEC$ ATTRIBUTES DLLEXPORT :: process
#endif
INTEGER :: process
CHARACTER(LEN = *), INTENT(IN) :: script
process = process_(script, LEN(script))
END FUNCTION
END MODULE
我能够使用 IFORT(在 Windows 中)成功编译此模块,同时作为共享库和静态库。
此外,我能够成功编译一个使用共享库的 Fortran 小程序(名为 example.f90
)。小程序如下:
PROGRAM Example
USE Test
INTEGER :: state
state = process("Hello world!")
END PROGRAM
现在,当我这次尝试使用静态库编译相同的小型 Fortran 程序时,出现以下错误:
C:\workspace\>ifort.exe /Qopenmp /module:library library\Test.lib example.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 16.0 Build 20160811
Copyright (C) 1985-2016 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
-out:example.exe
-subsystem:console
-defaultlib:libiomp5md.lib
-nodefaultlib:vcomp.lib
-nodefaultlib:vcompd.lib
library\Test.lib
example.obj
example.obj : error LNK2019: unresolved external symbol __imp_TEST_mp_process referenced in function MAIN__
example.exe : fatal error LNK1120: 1 unresolved externals
知道如何解决这个问题吗?
当你使用模块时,常规进程中的 DLLEXPORT 变成了 DLLIMPORT(这是一个添加了一些版本的功能,但我不记得确切的时间。)因此编译器假设进程来自一个DLL 并添加 __imp_ 前缀,但由于您将库构建为静态库,因此找不到。您可以 1) 删除 DLLEXPORT,2) 使用基于 _DLL 符号(为 DLL 构建预定义)的条件编译以仅在那时启用 DLLEXPORT,3) 将库构建为 DLL。
我还要提醒您,link 步骤中的库和对象的顺序可能很重要,但我认为此处无关紧要。我建议在构建可执行文件时将库放在源代码之后。
给定以下 Fortran 模块:
MODULE Test
IMPLICIT NONE
INTERFACE
INTEGER(c_int) FUNCTION process_(script, script_size) BIND(C, name = "process")
USE, INTRINSIC :: iso_c_binding, ONLY: c_int, c_char
CHARACTER(c_char), INTENT(IN) :: script(*)
INTEGER(c_int), INTENT(IN), VALUE :: script_size
END FUNCTION
END INTERFACE
CONTAINS
FUNCTION process(script)
#ifdef SHARED_LIB
!DEC$ ATTRIBUTES DLLEXPORT :: process
#endif
INTEGER :: process
CHARACTER(LEN = *), INTENT(IN) :: script
process = process_(script, LEN(script))
END FUNCTION
END MODULE
我能够使用 IFORT(在 Windows 中)成功编译此模块,同时作为共享库和静态库。
此外,我能够成功编译一个使用共享库的 Fortran 小程序(名为 example.f90
)。小程序如下:
PROGRAM Example
USE Test
INTEGER :: state
state = process("Hello world!")
END PROGRAM
现在,当我这次尝试使用静态库编译相同的小型 Fortran 程序时,出现以下错误:
C:\workspace\>ifort.exe /Qopenmp /module:library library\Test.lib example.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 16.0 Build 20160811
Copyright (C) 1985-2016 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
-out:example.exe
-subsystem:console
-defaultlib:libiomp5md.lib
-nodefaultlib:vcomp.lib
-nodefaultlib:vcompd.lib
library\Test.lib
example.obj
example.obj : error LNK2019: unresolved external symbol __imp_TEST_mp_process referenced in function MAIN__
example.exe : fatal error LNK1120: 1 unresolved externals
知道如何解决这个问题吗?
当你使用模块时,常规进程中的 DLLEXPORT 变成了 DLLIMPORT(这是一个添加了一些版本的功能,但我不记得确切的时间。)因此编译器假设进程来自一个DLL 并添加 __imp_ 前缀,但由于您将库构建为静态库,因此找不到。您可以 1) 删除 DLLEXPORT,2) 使用基于 _DLL 符号(为 DLL 构建预定义)的条件编译以仅在那时启用 DLLEXPORT,3) 将库构建为 DLL。
我还要提醒您,link 步骤中的库和对象的顺序可能很重要,但我认为此处无关紧要。我建议在构建可执行文件时将库放在源代码之后。