陳彥瑾
(河海大學 水利水電學院,江蘇 南京)
Fortran 語言是世界上最早出現的計算機高級編程語言,在科學和工程計算領域相比其他編程語言更具優勢。即使在計算機語言發展到今天的多元時代,Fortran 語言仍在廣泛使用[1-2]。因此,完善其使用方法或功能,還是有一定意義的。
王柯等[1]基于Fortran 語言,分析了糧堆溫度、水分含量、儲糧害蟲增長量以及殺蟲劑濃度衰減的變化。楊成坤等[2]研發地下及井中探測軟件平臺,其中很多模塊由Fortran 語言編寫。齊云飛、胡凡[3]基于Fortran與VB 混合編程建立了水庫群聯合優化調度系統。很多高校至今仍將Fortran 語言列為本科生教學主干課程[4]。
使用靜態鏈接庫對部分程序進行封裝是常用的手段之一,使用很廣泛。本文主要介紹在Fortran PowerStation 4.0 環境下建立靜態鏈接庫,利用主程序調用靜態庫的方法,并結合示例程序介紹該方法的使用。
首次建立靜態鏈接庫項目工作空間時,需要在Fortran Powerstation 4.0 環境下打開 Microsoft Developer Studio,執行File-New 命令,在彈出的新建(New)窗口中選擇項目工作空間(Project Workspace),如圖1 所示,點擊OK 后在New Project Workspace 對話框中選擇項目類型(Type)為Static Library(靜態鏈接庫),輸入項目文件名稱如Sub,軟件默認的文件存儲位置為“C:MSDEVProjects”,點擊Creat 后會在Projects 目錄(即文件夾,以下所謂“目錄”均指文件夾)下生成名為Sub 的項目文件夾,Sub 目錄內生成Sub.mak 文件。這時,靜態鏈接庫的項目工作空間已經建立完成,接下來就可以準備輸入靜態庫程序代碼。

圖1 Fortran Powerstation 4.0 新建文件建立方法
執行File-New 命令,在新建文件對話框中選擇Text File (或工具欄中選擇New Source File),生成Text1 文件,文件類型保存(File-Save)為Sublib.for,然后輸入程序代碼。靜態鏈接庫的程序代碼與一般子程序的編寫規則完全一樣。程序代碼編寫完成并存盤后,執行工具欄中Compile 命令 (或菜單欄Bulid-Compile Sublib.for)編譯Fortran 程序,此時彈窗提示“This File is not included in the Project”,確認添加即可。
Fortran Powerstation 4.0 軟件默認的編譯模式是Win32 Debug 模式,信息欄中提示編譯正常通過之后,會在Sub 目錄下建立Debug 文件夾并生成Sublib.obj 文件。執行工具欄中Build 命令 (或菜單欄Bulid-Bulid Sublib.lib)建立鏈接庫,在Debug 目錄下生成Sub.lib 文件,此文件即為新建立的靜態鏈接庫文件。由于鏈接庫文件一般不需要經常修改,只要聲明程序接入點便可使用,因此可以在編譯程序時選擇Release 模式,以提高執行效率。此時會對應生成Release 目錄及相應的obj 和lib 文件。
如果用來做靜態鏈接庫的程序代碼已存在,即Sublib.for 文件已有,就只需要將其添加到靜態庫項目工作空間中去。建立好的項目工作空間(即Projecct Workspace-Static Library)后,執行菜單欄Insert-Files into Project 命令,在彈出的對話框中找到Sublib.for 程序代碼,點擊OK。執行Compile 和Bulid 命令后,會對應在Sub 文件夾的debug 或Release 目錄生成Sublib.obj 和Sub.lib 文件。
主程序代碼中不包含鏈接庫代碼,主程序調用時只要知道鏈接庫中子程序名稱或模塊名稱即可。假定此時靜態庫Sub.lib 文件已經生成,主程序也已經完成。剩下的工作就是如何運行主程序,并調用靜態庫,完成相應計算任務。
在主程序代碼Program Main 后添加語句“!MS$OBJCOMMENT LIB:'Sub.lib'”可以實現靜態庫的添加。其中“!”在此處是偽注釋的用法,用來聲明將Sub.lib鏈接庫文件添加到主程序中。該行在編譯的過程中并不是注釋語句,可以與編譯器進行通訊,不可缺失。
當主程序調用(靜態庫中的)子程序,如Sub1 時,只需在主程序代碼中需要調用Sub1 的位置使用Call sub1 語句來聲明調用子程序,其中Sub1 為子程序名。當然,需要注意的是需將名為Sub.lib 的鏈接庫文件存放到主程序所在的目錄下連接時才可以搜索到。此時,便可打開主程序,如A.for,執行Bulid 命令,可以看到編譯連接成功,即可執行Bulid Execute A.exe,主程序會調用靜態庫中子程序Sub1 完成計算。
一些程序封裝為模塊使用起來可能更方便,只要在主程序代碼中使用Use ModD 語句就可調用模塊中相應函數及子程序,其中ModD 為模塊名。將Module模塊編譯為靜態庫時,同樣要先建立Static Library 類型的名為Module 項目工作空間。含Module 模塊的靜態庫程序代碼Mod.for 結構如下:
Module ModD
Contains
……
End Subroutine
End Module
中間省略的代碼為子程序代碼,需要指出此時子程序結束語句應當用End Subroutine 而不能采用省略Subroutine 的End 形式。依次執行Compile 和Bulid 命令,在Debug 或Release 目錄下會生成modd.mod、Mod.obj 文件和Module.lib 文件。擴展名mod 文件為模塊,lib 文件為靜態庫文件。
主程序接入含Module 模塊的靜態庫時首先使用語句“!MS$ OBJCOMMENT LIB: 'Module.lib'”添加靜態庫,使用模塊時需要用Use ModD 語句聲明使用,使用Call sub 命令可調用相應的子程序。此處需要注意的是,應將modd.mod 模塊文件和Module.lib 鏈接庫文件同時存放到主程序的目錄下。
鏈接庫可以嵌套使用,因此在將Module 模塊編譯為鏈接庫時也可調用其他靜態庫。
由于不同問題的復雜性,往往要對程序進行不斷改進來適應更多的情況,因此就需要對已經生成的靜態鏈接庫進行不定期的更新和維護。
首先確認Sub.mdp 及Sub.mak 文件存在,執行菜單欄File-Open Workspace 命令,在Open Project Workspace 窗口中打開sub.mdp 文件,在項目空間樹形菜單中雙擊Sublib.for 可修改程序代碼文件,修改存盤后執行Bulid 命令就可以在Debug 或Release 目錄下建立新的Sub.Lib 文件。
需要指出,靜態庫進行更新維護后,重新生成了Sub.lib 文件。需將此新靜態庫文件存放到主程序目錄下,而且主程序在使用前必須重新編譯連接生成新的A.exe。這是因為舊的可執行程序A.exe 是將更新前的鏈接庫程序編譯到了A.exe 中,如果只重新鏈接或只執行舊的可執行程序,則調用的鏈接庫仍為上次編譯的更新前的內容,因此,必須重新編譯連接主程序代碼生成新的A.exe 方可使用新靜態庫。
本節結合Fortran 語言編寫的有限元計算程序中一部分功能,詳細介紹使用靜態鏈接庫的具體步驟。
示例子程序的功能為:通過讀取線彈性材料的彈性常數彈性模量E 和泊松比ν,形成有限元法中使用的物理方程的彈性矩陣D,計算公式如式(1)。
矩陣D 完全由E 和ν 決定,可以把由E 和ν形成D 的過程建立為靜態庫,主程序只要提供材料的E 和ν 值,通過調用靜態庫中對應的子程序SubD 即可得到材料彈性矩陣D。子程序代碼見表1。

表1 材料彈性矩陣D 子程序
建立名為Sub 項目類型為Static Library 的項目文件目錄,添加鏈接庫程序代碼Sublib.for,以Win32 Release 模式執行Compile 及Bulid 命令,編譯連接程序后會在Sub 目錄下生成Sub.mak,sub.mdp 文件,Release 目錄下生成Sub.lib、Sublib.obj 文件,其中Sub.lib 即是所需要的靜態庫文件,主程序調用時只要在程序代碼中聲明程序接入點即可調用鏈接庫中子程序。
在主程序中使用語句“!MS$ OBJCOMMENT LIB:'Sub.lib'”調用靜態庫,使用Call SubD 語句調用靜態庫中相應子程序。主程序代碼如表2 所示。

表2 材料彈性矩陣D 子程序
用Microsoft Developer Studio 打開主程序代碼Main.for 文件,確認之前項目空間關閉后,執行Compile 和Bulid 命令,編譯鏈接主程序代碼。注意,此處需將Sub 文件夾Release 目錄下的Sub.lib 文件存放到當前主程序目錄下,主程序調用鏈接庫時才可搜索到。當鏈接庫中含有Module 模塊時,項目空間建立方法,需要將Modd.mod 模塊和Module.lib 鏈接庫文件一并放到主程序目錄下方可鏈接成功。本例輸入文件E-v.dat 數據為第一行2;第二行為50000.0,0.30;第三行為100000.0,0.25。
執行Bulid-Bulid Execute Main.exe,輸出上述兩種材料的6*6 的彈性矩陣D,說明主程序調用Sub.lib鏈接庫的SubD 子程序形成矩陣D 是成功的。主程序得到的矩陣D 結果如下:
本文詳細的介紹了在Fortran Powerstation 4.0 環境下建立靜態鏈接庫并在主程序中調用靜態庫里子程序的使用方法,主要結論如下:
(1) 本文介紹的靜態鏈接庫的建立和使用十分方便,可方便地用于大型程序中通用子程序的封裝,具有較強的實用價值。
(2) 靜態鏈接庫可以包含多個子程序及Module模塊,靜態庫之間也可以嵌套使用,主程序亦可以同時調用多個靜態庫,其適用性很強。
(3) Fortran Powerstation4.0 環境下使用靜態鏈接庫方法十分簡單,只需在主程序代碼中添加一行語句,編譯連接主程序就可以使用。