【发布时间】:2016-04-28 14:42:54
【问题描述】:
我们当前的解决方案是 Visual Studio 2013 中的混合 C++ Fortran 应用程序,每个应用程序大约有 40 个项目。
虽然我们可以很好地构建解决方案,但我们收到了大约 6000 个警告 - 其中绝大多数是 LNK4006 警告,其中一个函数正在“复制”:
warning LNK4006: _XXXXXXXXXXX@8 already defined in project1.lib(module1.obj); second definition ignored project2.lib(module1.obj)
共同点是被复制的函数是在 Fortran 模块中定义的——其中许多只是 C++ 函数的接口:
MODULE mINTERFACES
USE ISO_C_BINDING
INTERFACE
INTEGER(4) FUNCTION GetLastErrorCode [C, ALIAS: '_GetLastErrorCode'] (index)
USE ISO_C_BINDING
INTEGER(C_SIZE_T), INTENT(IN) :: index
END FUNCTION GetLastErrorCode
END INTERFACE
END
由于这些模块在许多 Fortran 项目中使用,每个项目都有一个独立版本的接口函数 - 因此是重复的。
这一切都很有道理,但我的问题是:我可以忽略警告(即在项目配置中排除它们)吗?我看不到任何明显的方法来重组我们的代码以删除警告,我的印象是将这些接口放在一个模块中是一种很好的做法......
【问题讨论】:
-
[C, ALIAS: '_GetLastErrorCode']是什么语法?以及如何在 C++ 中定义函数?你用extern "C"吗? -
这是一个用于 C 互操作性的 Microsoft Powerstation 扩展。已经死了 20 年的编译器的语法与 Fortran 2003 的 ISO_C_BINDING 的组合正在引起我的注意。
-
Visual Studio 不附带 Fortran 编译器。您使用的是哪种特定的 Fortran 产品?这样的接口块应该只导致符号引用,而不是定义。从错误消息来看,您似乎在多个库中具有相同的目标代码 - 即您已编译 module1.f90 两次或更多次 - 是这种情况吗?
-
这不仅仅是接口块——模块中还声明了其他函数及其主体,这些函数也会收到“重复”警告。
-
(我现在在英特尔论坛上也看到了这个问题。)您不应该将模块源代码包含在同一程序的多个项目中。这将创建多个定义,并且取决于其他细节,很可能是有问题的。一个项目应该单独编译模块的源代码,其他项目应该只引用编译的 mod 文件。在 Visual Studio 中的 Intel Fortran 集成中,通过让其他项目“依赖”具有模块源的项目,这很容易设置。
标签: c++ visual-studio linker fortran