陳彥瑾
(河海大學(xué) 水利水電學(xué)院,江蘇 南京)
Fortran 語(yǔ)言是世界上最早出現(xiàn)的計(jì)算機(jī)高級(jí)編程語(yǔ)言,在科學(xué)和工程計(jì)算領(lǐng)域相比其他編程語(yǔ)言更具優(yōu)勢(shì)。即使在計(jì)算機(jī)語(yǔ)言發(fā)展到今天的多元時(shí)代,F(xiàn)ortran 語(yǔ)言仍在廣泛使用[1-2]。因此,完善其使用方法或功能,還是有一定意義的。
王柯等[1]基于Fortran 語(yǔ)言,分析了糧堆溫度、水分含量、儲(chǔ)糧害蟲(chóng)增長(zhǎng)量以及殺蟲(chóng)劑濃度衰減的變化。楊成坤等[2]研發(fā)地下及井中探測(cè)軟件平臺(tái),其中很多模塊由Fortran 語(yǔ)言編寫(xiě)。齊云飛、胡凡[3]基于Fortran與VB 混合編程建立了水庫(kù)群聯(lián)合優(yōu)化調(diào)度系統(tǒng)。很多高校至今仍將Fortran 語(yǔ)言列為本科生教學(xué)主干課程[4]。
使用靜態(tài)鏈接庫(kù)對(duì)部分程序進(jìn)行封裝是常用的手段之一,使用很廣泛。本文主要介紹在Fortran PowerStation 4.0 環(huán)境下建立靜態(tài)鏈接庫(kù),利用主程序調(diào)用靜態(tài)庫(kù)的方法,并結(jié)合示例程序介紹該方法的使用。
首次建立靜態(tài)鏈接庫(kù)項(xiàng)目工作空間時(shí),需要在Fortran Powerstation 4.0 環(huán)境下打開(kāi) Microsoft Developer Studio,執(zhí)行File-New 命令,在彈出的新建(New)窗口中選擇項(xiàng)目工作空間(Project Workspace),如圖1 所示,點(diǎn)擊OK 后在New Project Workspace 對(duì)話框中選擇項(xiàng)目類(lèi)型(Type)為Static Library(靜態(tài)鏈接庫(kù)),輸入項(xiàng)目文件名稱如Sub,軟件默認(rèn)的文件存儲(chǔ)位置為“C:MSDEVProjects”,點(diǎn)擊Creat 后會(huì)在Projects 目錄(即文件夾,以下所謂“目錄”均指文件夾)下生成名為Sub 的項(xiàng)目文件夾,Sub 目錄內(nèi)生成Sub.mak 文件。這時(shí),靜態(tài)鏈接庫(kù)的項(xiàng)目工作空間已經(jīng)建立完成,接下來(lái)就可以準(zhǔn)備輸入靜態(tài)庫(kù)程序代碼。
圖1 Fortran Powerstation 4.0 新建文件建立方法
執(zhí)行File-New 命令,在新建文件對(duì)話框中選擇Text File (或工具欄中選擇New Source File),生成Text1 文件,文件類(lèi)型保存(File-Save)為Sublib.for,然后輸入程序代碼。靜態(tài)鏈接庫(kù)的程序代碼與一般子程序的編寫(xiě)規(guī)則完全一樣。程序代碼編寫(xiě)完成并存盤(pán)后,執(zhí)行工具欄中Compile 命令 (或菜單欄Bulid-Compile Sublib.for)編譯Fortran 程序,此時(shí)彈窗提示“This File is not included in the Project”,確認(rèn)添加即可。
Fortran Powerstation 4.0 軟件默認(rèn)的編譯模式是Win32 Debug 模式,信息欄中提示編譯正常通過(guò)之后,會(huì)在Sub 目錄下建立Debug 文件夾并生成Sublib.obj 文件。執(zhí)行工具欄中Build 命令 (或菜單欄Bulid-Bulid Sublib.lib)建立鏈接庫(kù),在Debug 目錄下生成Sub.lib 文件,此文件即為新建立的靜態(tài)鏈接庫(kù)文件。由于鏈接庫(kù)文件一般不需要經(jīng)常修改,只要聲明程序接入點(diǎn)便可使用,因此可以在編譯程序時(shí)選擇Release 模式,以提高執(zhí)行效率。此時(shí)會(huì)對(duì)應(yīng)生成Release 目錄及相應(yīng)的obj 和lib 文件。
如果用來(lái)做靜態(tài)鏈接庫(kù)的程序代碼已存在,即Sublib.for 文件已有,就只需要將其添加到靜態(tài)庫(kù)項(xiàng)目工作空間中去。建立好的項(xiàng)目工作空間(即Projecct Workspace-Static Library)后,執(zhí)行菜單欄Insert-Files into Project 命令,在彈出的對(duì)話框中找到Sublib.for 程序代碼,點(diǎn)擊OK。執(zhí)行Compile 和Bulid 命令后,會(huì)對(duì)應(yīng)在Sub 文件夾的debug 或Release 目錄生成Sublib.obj 和Sub.lib 文件。
主程序代碼中不包含鏈接庫(kù)代碼,主程序調(diào)用時(shí)只要知道鏈接庫(kù)中子程序名稱或模塊名稱即可。假定此時(shí)靜態(tài)庫(kù)Sub.lib 文件已經(jīng)生成,主程序也已經(jīng)完成。剩下的工作就是如何運(yùn)行主程序,并調(diào)用靜態(tài)庫(kù),完成相應(yīng)計(jì)算任務(wù)。
在主程序代碼Program Main 后添加語(yǔ)句“!MS$OBJCOMMENT LIB:'Sub.lib'”可以實(shí)現(xiàn)靜態(tài)庫(kù)的添加。其中“!”在此處是偽注釋的用法,用來(lái)聲明將Sub.lib鏈接庫(kù)文件添加到主程序中。該行在編譯的過(guò)程中并不是注釋語(yǔ)句,可以與編譯器進(jìn)行通訊,不可缺失。
當(dāng)主程序調(diào)用(靜態(tài)庫(kù)中的)子程序,如Sub1 時(shí),只需在主程序代碼中需要調(diào)用Sub1 的位置使用Call sub1 語(yǔ)句來(lái)聲明調(diào)用子程序,其中Sub1 為子程序名。當(dāng)然,需要注意的是需將名為Sub.lib 的鏈接庫(kù)文件存放到主程序所在的目錄下連接時(shí)才可以搜索到。此時(shí),便可打開(kāi)主程序,如A.for,執(zhí)行Bulid 命令,可以看到編譯連接成功,即可執(zhí)行Bulid Execute A.exe,主程序會(huì)調(diào)用靜態(tài)庫(kù)中子程序Sub1 完成計(jì)算。
一些程序封裝為模塊使用起來(lái)可能更方便,只要在主程序代碼中使用Use ModD 語(yǔ)句就可調(diào)用模塊中相應(yīng)函數(shù)及子程序,其中ModD 為模塊名。將Module模塊編譯為靜態(tài)庫(kù)時(shí),同樣要先建立Static Library 類(lèi)型的名為Module 項(xiàng)目工作空間。含Module 模塊的靜態(tài)庫(kù)程序代碼Mod.for 結(jié)構(gòu)如下:
Module ModD
Contains
……
End Subroutine
End Module
中間省略的代碼為子程序代碼,需要指出此時(shí)子程序結(jié)束語(yǔ)句應(yīng)當(dāng)用End Subroutine 而不能采用省略Subroutine 的End 形式。依次執(zhí)行Compile 和Bulid 命令,在Debug 或Release 目錄下會(huì)生成modd.mod、Mod.obj 文件和Module.lib 文件。擴(kuò)展名mod 文件為模塊,lib 文件為靜態(tài)庫(kù)文件。
主程序接入含Module 模塊的靜態(tài)庫(kù)時(shí)首先使用語(yǔ)句“!MS$ OBJCOMMENT LIB: 'Module.lib'”添加靜態(tài)庫(kù),使用模塊時(shí)需要用Use ModD 語(yǔ)句聲明使用,使用Call sub 命令可調(diào)用相應(yīng)的子程序。此處需要注意的是,應(yīng)將modd.mod 模塊文件和Module.lib 鏈接庫(kù)文件同時(shí)存放到主程序的目錄下。
鏈接庫(kù)可以嵌套使用,因此在將Module 模塊編譯為鏈接庫(kù)時(shí)也可調(diào)用其他靜態(tài)庫(kù)。
由于不同問(wèn)題的復(fù)雜性,往往要對(duì)程序進(jìn)行不斷改進(jìn)來(lái)適應(yīng)更多的情況,因此就需要對(duì)已經(jīng)生成的靜態(tài)鏈接庫(kù)進(jìn)行不定期的更新和維護(hù)。
首先確認(rèn)Sub.mdp 及Sub.mak 文件存在,執(zhí)行菜單欄File-Open Workspace 命令,在Open Project Workspace 窗口中打開(kāi)sub.mdp 文件,在項(xiàng)目空間樹(shù)形菜單中雙擊Sublib.for 可修改程序代碼文件,修改存盤(pán)后執(zhí)行Bulid 命令就可以在Debug 或Release 目錄下建立新的Sub.Lib 文件。
需要指出,靜態(tài)庫(kù)進(jìn)行更新維護(hù)后,重新生成了Sub.lib 文件。需將此新靜態(tài)庫(kù)文件存放到主程序目錄下,而且主程序在使用前必須重新編譯連接生成新的A.exe。這是因?yàn)榕f的可執(zhí)行程序A.exe 是將更新前的鏈接庫(kù)程序編譯到了A.exe 中,如果只重新鏈接或只執(zhí)行舊的可執(zhí)行程序,則調(diào)用的鏈接庫(kù)仍為上次編譯的更新前的內(nèi)容,因此,必須重新編譯連接主程序代碼生成新的A.exe 方可使用新靜態(tài)庫(kù)。
本節(jié)結(jié)合Fortran 語(yǔ)言編寫(xiě)的有限元計(jì)算程序中一部分功能,詳細(xì)介紹使用靜態(tài)鏈接庫(kù)的具體步驟。
示例子程序的功能為:通過(guò)讀取線彈性材料的彈性常數(shù)彈性模量E 和泊松比ν,形成有限元法中使用的物理方程的彈性矩陣D,計(jì)算公式如式(1)。
矩陣D 完全由E 和ν 決定,可以把由E 和ν形成D 的過(guò)程建立為靜態(tài)庫(kù),主程序只要提供材料的E 和ν 值,通過(guò)調(diào)用靜態(tài)庫(kù)中對(duì)應(yīng)的子程序SubD 即可得到材料彈性矩陣D。子程序代碼見(jiàn)表1。
表1 材料彈性矩陣D 子程序
建立名為Sub 項(xiàng)目類(lèi)型為Static Library 的項(xiàng)目文件目錄,添加鏈接庫(kù)程序代碼Sublib.for,以Win32 Release 模式執(zhí)行Compile 及Bulid 命令,編譯連接程序后會(huì)在Sub 目錄下生成Sub.mak,sub.mdp 文件,Release 目錄下生成Sub.lib、Sublib.obj 文件,其中Sub.lib 即是所需要的靜態(tài)庫(kù)文件,主程序調(diào)用時(shí)只要在程序代碼中聲明程序接入點(diǎn)即可調(diào)用鏈接庫(kù)中子程序。
在主程序中使用語(yǔ)句“!MS$ OBJCOMMENT LIB:'Sub.lib'”調(diào)用靜態(tài)庫(kù),使用Call SubD 語(yǔ)句調(diào)用靜態(tài)庫(kù)中相應(yīng)子程序。主程序代碼如表2 所示。
表2 材料彈性矩陣D 子程序
用Microsoft Developer Studio 打開(kāi)主程序代碼Main.for 文件,確認(rèn)之前項(xiàng)目空間關(guān)閉后,執(zhí)行Compile 和Bulid 命令,編譯鏈接主程序代碼。注意,此處需將Sub 文件夾Release 目錄下的Sub.lib 文件存放到當(dāng)前主程序目錄下,主程序調(diào)用鏈接庫(kù)時(shí)才可搜索到。當(dāng)鏈接庫(kù)中含有Module 模塊時(shí),項(xiàng)目空間建立方法,需要將Modd.mod 模塊和Module.lib 鏈接庫(kù)文件一并放到主程序目錄下方可鏈接成功。本例輸入文件E-v.dat 數(shù)據(jù)為第一行2;第二行為50000.0,0.30;第三行為100000.0,0.25。
執(zhí)行Bulid-Bulid Execute Main.exe,輸出上述兩種材料的6*6 的彈性矩陣D,說(shuō)明主程序調(diào)用Sub.lib鏈接庫(kù)的SubD 子程序形成矩陣D 是成功的。主程序得到的矩陣D 結(jié)果如下:
本文詳細(xì)的介紹了在Fortran Powerstation 4.0 環(huán)境下建立靜態(tài)鏈接庫(kù)并在主程序中調(diào)用靜態(tài)庫(kù)里子程序的使用方法,主要結(jié)論如下:
(1) 本文介紹的靜態(tài)鏈接庫(kù)的建立和使用十分方便,可方便地用于大型程序中通用子程序的封裝,具有較強(qiáng)的實(shí)用價(jià)值。
(2) 靜態(tài)鏈接庫(kù)可以包含多個(gè)子程序及Module模塊,靜態(tài)庫(kù)之間也可以嵌套使用,主程序亦可以同時(shí)調(diào)用多個(gè)靜態(tài)庫(kù),其適用性很強(qiáng)。
(3) Fortran Powerstation4.0 環(huán)境下使用靜態(tài)鏈接庫(kù)方法十分簡(jiǎn)單,只需在主程序代碼中添加一行語(yǔ)句,編譯連接主程序就可以使用。