2016-04-28 43 views
0

我们当前的解决方案是Visual Studio 2013中的混合C++ Fortran应用程序,每个应用程序大约有40个项目。混合的Fortran/C++解决方案中可以安全地忽略LNK4006警告吗?

虽然我们可以构建解决方案就好了,我们得到约6000警告 - 绝大多数这些都是LNK4006警告,其中一个功能被“复制”:

warning LNK4006: [email protected] 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项目中使用的,每个项目具有接口功能的一个独立的版本 - H因为重复。

这一切都很合理,但我的问题是:我可以忽略警告(即在项目配置中排除它们)吗?我看不出任何明显的方式来重组我们的代码来删除警告,我的印象是,将这些接口放在一个模块中是很好的做法...

+0

'[C,ALIAS:'_GetLastErrorCode']'是什么语法?你如何在C++中定义函数?你用'extern“C”'? –

+1

这是针对C互操作性的Microsoft Powerstation扩展。语法的一个编译器,它已经死了二十年,按照Fortran 2003的ISO_C_BINDING的组合做我的头。 – IanH

+0

Visual Studio中没有附带一个Fortran编译。您正在使用哪种特定的Fortran产品?这样一个接口块应该只能产生一个符号引用,而不是一个定义。从错误消息中,您看起来在多个库中具有相同的目标代码 - 即,您已经编译了两次或更多的module1.f90 - 是这种情况吗? – IanH

回答

0

我要感谢所有那些建设性地评论过在这个主题中 - 还包括@IanH和Steve Lionel,他们在英特尔论坛主题https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/628995上提供了帮助。

在短期

(这是我自己的判断而不是别人的),在这种特殊情况下的警告多余的,但如果你禁用它们,你会错过任何新的警告,这可能是非常重要的。恕我直言,这意味着你不应该禁用警告。

长的答案

的警告从两个来源的:

  1. 的公约已经长大了使用一个模块来包含“全局”的数据,而是通过“存取访问此功能“,这些功能在与模块相同的文件中定义。这意味着当模块被包含在许多不同的项目中时,访问器函数被多次编译。
  2. 其中几个模块包含C接口块(这是很好的做法),但对于返回字符串的函数,使用的范例如Creating a FORTRAN interface to a C function that returns a char*中所述。虽然接口块本身没有引起重复警告,但是将C指针转换为Fortran字符串的第二功能却没有发生。

解决方案本来可以将所有这些访问器函数和辅助接口例程提取到单独的文件中,并且只编译一次,但这需要花费数周时间。

感谢@IanH,他指出你可以通过在一个单独的项目中定义所有模块,然后(在Visual Studio中)将所有项目设置为依赖于这个新的“共享模块“项目(使用Build Dependencies - > Project Dependencies)。现在编译没有警告; VS的“整个解决方案”搜索现在只能找到每个例程一次;它可能编译速度更快!总而言之,一场胜利。