2016-04-28 37 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的「整個解決方案」搜索現在只能找到每個例程一次;它可能編譯速度更快!總而言之,一場勝利。