3、兩種系統動态庫比較分析 Windows和Linux采用動态連結庫技術目的是基本一緻的,但由于作業系統的不同,他們在許多方面還是不盡相同,下面從以下幾個方面進行闡述。 (1)動态庫程式編寫,在Windows系統下的執行檔案格式是PE格式,動态庫需要一個DllMain函數作為初始化的人口,通常在導出函數的聲明時需要有_declspec(dllexport)關鍵字。Linux下的gcc編譯的執行檔案預設是ELF格式,不需要初始化入口,亦不需要到函數做特别聲明,編寫比較友善。 (2)動态庫編譯,在windows系統下面,有友善的調試編譯環境,通常不用自己去編寫makefile檔案,但在linux下面,需要自己動手去編寫makefile檔案,是以,必須掌握一定的makefile編寫技巧,另外,通常Linux編譯規則相對嚴格。 (3)動态庫調用方面,Windows和Linux對其下編制的動态庫都可以采用顯式調用或隐式調用,但具體的調用方式也不盡相同。 (4)動态庫輸出函數檢視,在Windows中,有許多工具和軟體可以進行檢視DLL中所輸出的函數,例如指令行方式的dumpbin以及VC 工具中的DEPENDS程式。在Linux系統中通常采用nm來檢視輸出函數,也可以使用ldd檢視程式隐式連結的共享對象檔案。 (5)對作業系統的依賴,這兩種動态庫運作依賴于各自的作業系統,不能跨平台使用。是以,對于實作相同功能的動态庫,必須為兩種不同的作業系統提供不同的動态庫版本。 4、動态庫移植方法 如果要編制在兩個系統中都能使用的動态連結庫,通常會先選擇在Windows的VC 提供的調試環境中完成初始的開發,畢竟VC 提供的圖形化編輯和調試界面比vi和gcc友善許多。完成測試之後,再進行動态庫的程式移植。通常gcc預設的編譯規則比VC 預設的編譯規則嚴格,即使在VC 下面沒有任何警告錯誤的程式在gcc調試中也會出現許多警告錯誤,可以在gcc中采用-w選項關閉警告錯誤。 下面給出程式移植需要遵循的規則以及經驗。 (1)盡量不要改變原有動态庫頭檔案的順序。通常在C/C 語言中,頭檔案的順序有相當的關系。另外雖然C/C 語言區分大小寫,但在包含頭檔案時,Linux必須與頭檔案的大小寫相同,因為ext2檔案系統對檔案名是大小寫敏感,否則不能正确編譯,而在Windows下面,頭檔案大小寫可以正确編譯。 (2)不同系統獨有的頭檔案。在Windows系統中,通常會包括windows.h頭檔案,如果調用底層的通信函數,則會包含winsock..h頭檔案。是以在移植到Linux系統時,要注釋掉這些Windows系統獨有的頭檔案以及一些windows系統的常量定義說明,增加Linux都底層通信的支援的頭檔案等。 (3)資料類型。VC 具有許多獨有的資料類型,如__int16,__int32,TRUE,SOCKET等,gcc編譯器不支援它們。通常做法是需要将windows.h和basetypes.h中對這些資料進行定義的語句複制到一個頭檔案中,再在Linux中包含這個頭檔案。例如将套接字的類型為SOCKET改為int。 (4)關鍵字。VC 中具有許多标準C中所沒有采用的關鍵字,如BOOL,BYTE,DWORD,__asm等,通常在為了移植友善,盡量不使用它們,如果實在無法避免可以采用#ifdef 和#endif為LINUX和WINDOWS編寫兩個版本。 (5)函數原型的修改。通常如果采用标準的C/C 語言編寫的動态庫,基本上不用再重新編寫函數,但對于系統調用函數,由于兩種系統的差別,需要改變函數的調用方式等,如在Linux編制的網絡通信動态庫中,用close()函數代替windows作業系統下的closesocket()函數來關閉套接字。另外在Linux下沒有檔案句柄,要打開檔案可用open和fopen函數,具體這兩個函數的用法可參考文獻[2]。 (6)makefile的編寫。在windows下面通常由VC 編譯器來負責調試,但gcc需要自己動手編寫makefile檔案,也可以參照VC 生成的makefile檔案。對于動态庫移植,編譯動态庫時需要加入-shared選項。對于采用數學函數,如幂級數的程式,在調用動态庫是,需要加入-lm。 (7)其它一些需要注意的地方 ①程式設計結構分析,對于移植它人編寫的動态庫程式,程式結構分析是必不可少的步驟,通常在動态庫程式中,不會包含界面等操作,是以相對容易一些。 ②在Linux中,對檔案或目錄的權限分為擁有者、群組、其它。是以在存取檔案時,要注意對檔案是讀還是寫操作,如果是對檔案進行寫操作,要注意修改檔案或目錄的權限,否則無法對檔案進行寫。 ③指針的使用,定義一個指針隻給它配置設定四個位元組的記憶體,如果要對指針所指向的變量指派,必須用malloc函數為它配置設定記憶體或不把它定義為指針而定義為變量即可,這點在linux下面比windows編譯嚴格。同樣結構不能在函數中傳值,如果要在函數中進行結構傳值,必須把函數中的結構定義為結構指針。 ④路徑辨別符,在Linux下是“/”,在Windows下是“/”,注意windows和Linux的對動态庫搜尋路徑的不同。 ⑤程式設計和調試技巧方面。對不同的調試環境有不同的調試技巧,在這裡不多叙述。 5、結束語 本文系統分析了windows和Linux動态庫實作和使用方式,從程式編寫、編譯、調用以及對作業系統依賴等方面綜合分析比較了這兩種調用方式的不同之處,根據實際程式移植經驗,給出了将VC 編制的Windows動态庫移植到Linux下的方法以及需要注意的問題,同時并給出了程式示例片斷,實際在程式移植過程中,由于系統的設計等方面,可能移植起來需要注意的方面遠比上面複雜,本文通過總結歸納進而為不同作業系統程式移植提供了有意的經驗和技巧。 |