2012-05-31 84 views
4

我正在使用gfortran的95+擴展。我有一個實用程序模塊庫,我想鏈接到其他項目,即作爲庫或共享對象/ DLL。但是,在Fortran中,我不明白如何將接口從Fortran實現中分離出來,而不需要維護模塊接口的兩個副本。如何爲Fortran 95+模塊庫提供顯式接口,並隱藏實現

在C中,我將接口從象實現分離:

api.h ←includes← impl.h 
    ↑     ↑ 
includes   includes 
    ↑     ↑ 
user.c   impl.c 

有沒有辦法實現現代化的Fortran語言相同的效果?我是否需要爲用戶提供.mod文件的庫?

  • 顯式接口
  • 只有接口定義暴露給用戶代碼的單一定義

編輯:綜上所述(我認爲是)答案:

  • .mod文件是需要的,因爲它們包含顯式接口定義

  • 沒有標準的Fortran ABI的模塊 - .mod文件將是編譯器特定的

  • 唯一直接analgous的方法來實現隱藏的問題是子模塊,這是在2008年的Fortran定義,並gfortran不支持。

  • @ High-Performance-Mark和Fedora頁面提到的避免模塊的最實用方法是爲接口模塊分發包含文件以及用於實現的預編譯.mods。

  • 使用包含有一些衆所周知的令人討厭的旅程,包括潛在的重新定義通用塊。

我有點驚訝,這裏並沒有一個直截了當的答案。

回答

5

我相信你可以使用Fortran 2008編譯器與submodules做到這一點。從FortranWiki:

子模塊的Fortran 2008,其允許模塊中已經定義了一個模塊過程及其接口,同時具有在一個單獨的單元中,一個子模塊中定義的過程的主體的特徵。

Wikipedia(重點煤礦)

[子模塊允許]本說明書和實施的模塊,以在不同的程序單元,其改善的大文庫的包裝中表達,允許商業祕密保存同時發佈權威接口,並防止編譯級聯。

我對子模塊沒有任何經驗,但它們還沒有得到廣泛支持,但它們是需要注意的。

編輯由於許多編譯器不支持子模塊,因此討論其他選項可能很有幫助。

This page問這個類似的問題,並有一些不錯的鏈接。在討論Google網上論壇時特別有用(特別參見this post)。總之,一種選擇是:

  • 集團所有的庫函數/在單個文件中,並通過他們自己的子程序(即,不是作爲一個模塊的一部分)。

  • 創建一個模塊,該模塊只包含您想要公開給最終用戶的那些子例程的接口。

  • 爲最終用戶提供已編譯的模塊和庫。用戶然後可以在他/她的程序中模塊use並鏈接到庫。

這允許你「隱藏」你不想公開給最終用戶的函數/子程序。

從解禁後我鏈接到:

一些編譯器生成的.mod(或任何名稱的編譯器給它)文件和庫文件。 .mod文件具有符號;庫文件包含模塊中包含的可執行代碼。在這種情況下,您必須將這兩個文件分發給最終用戶。另外,一些編譯器(特別是f95)將符號和可執行代碼放入一個單一的.mod文件中。在這種情況下,您只需要將.mod文件提供給最終用戶。

(!最終)編輯上有Fedora的維基一useful page

理想的情況下,便攜式Fortran庫中會避免使用模塊。好消息是已經定義了子模塊規範,這將允許模塊的接口規範部分與過程源代碼分離。在[編譯器]中這是在Fortran編譯器中實現的,它應該被所有打包的庫使用。

2

的另一種方法來實現分離接口和用於寫入每個僅一次,即自FORTRAN77被大量使用(以及可能甚至在此之前)的方法是使用一個INCLUDE線,包括一個源文件的文本到另一個源文件中。避免INCLUDE有許多健全的軟件工程原因,並且在使用它們時有很多實際的用處。

我要補充,我喜歡克里斯已經不是訴諸包括概述更好的方法,但有時需要必須...

2

這取決於你想要做什麼。如果意圖是由於商業祕密而將代碼隱藏起來,那麼您可以編寫「接口」並提供預編譯的庫,而不是實際的代碼。用戶可以使用這些接口編譯這些文件,以便能夠調用您的過程。

如果你只是想練習暴露你可以只使用什麼是必要的模塊,並指定一些程序或模塊變量通過指定他們是「私人」是內部模塊的良好的編程習慣。一個人可以通過編輯器看到代碼,但程序不能在模塊外調用。您只能向程序的其餘部分透露應該使用的程序並隱藏其他程序。您可以使用模塊頂部的私有語句將「private」設置爲默認值,並指定需要在「public」語句中可見的過程。

除非您不希望您的用戶看到或編譯您的源代碼,否則我不會提供.mod文件。這就產生了支持各種編譯器的問題,而不是簡單地提供源代碼。 「私人」和「公共」聲明應該實現你的兩個目標:不重複接口定義,只暴露你想要接觸的接口。除非你的程序非常大或者還有其他問題,否則其他方法對我來說似乎過於複雜。