C 的可移植性和跨平台開發 5 作業系統

2021-08-23 13:02:34 字數 1999 閱讀 8065

上乙個帖子提到了「硬體體系」相關的話題,今天來說說和作業系統相關的話題。c++跨平台開發中和os相關的瑣事挺多,所以今天會囉嗦比較長的篇幅,請列位看官見諒 :-)

為了不繞口,以下把linux和各種unix統稱為posix系統。

檔案系統(filesystem以下簡稱fs)

剛開始搞跨平台開發的新手,多半都會碰上和fs相關的問題。所以先來聊一下fs。歸納下來,開發中容易碰上的fs差異主要有如下幾個:目錄分隔符的差異;大小寫敏感的差異;路徑中禁用字元的差異。

為了應對上述差異,你要注意如下幾點:

1、檔案和目錄命名要規範

在給檔案和目錄命名時,盡量只使用字母和數字。不要在同乙個目錄下放兩個名稱相似(名稱中只有大小寫不同,例如foo.cpp與foo.cpp)的檔案。不要使用某些os的保留字(例如aux、con、nul、prn)作檔名或目錄名。

補充一下,剛才說的命名,包括了源**檔案、二進位制檔案和執行時建立的其它檔案。

2、#include語句要規範

當你寫#include語句時,要注意使用正斜線「/」(比較通用)而不要使用反斜線「\」(僅在windows可用)。#include語句中的檔案和目錄名要和實際名稱保持大小寫完全一致。

3、**中涉及fs操作,盡量使用現成的庫

已經有很多成熟的、用於fs的第三方庫(比如boost::filesystem)。如果你的**涉及到fs的操作(比如目錄遍歷),盡量使用這些第三方庫,可以幫你省不少事情。

文字檔案的回車cr/換行lf

由於幾個知名的作業系統對回車/換行的處理不一致,導致了這個煩人的問題。目前的局面是:windows同時使用cr和lf;linux和大部分的unix使用lf;蘋果的mac系列使用cr。

對於源**管理,好在很多版本管理軟體(比如cvs、svn)都會智慧型地處理這個問題,讓你從**庫取回本地的原始碼能適應本地的格式。

如果你的程式需要在執行時處理文字檔案,要留意本文方式開啟和二進位制方式開啟的區別。另外,如果涉及跨不同系統傳輸文字檔案,要考慮進行適當的處理。

檔案搜尋路徑(包括搜尋可執行檔案和動態庫)

在windows下,如果要執行檔案或者載入動態庫,一般會搜尋當前目錄;而posix系統則不盡然。所以如果你的應用涉及到啟動程序或載入動態庫,就要小心這個差異。

環境變數

如果你的應用程式使用動態庫,強烈建議動態庫匯出標準c風格的函式(盡量不要匯出類)。如果在posix系統中載入動態庫,切記慎用rtld_global標誌位。這個標誌位會enable全域性符號表,有可能會導致多個動態庫之間的符號名衝突(一旦碰到這種事,會出現匪夷所思的執行時錯誤,極難除錯)。

關於動態庫的話題比較大,限於篇幅,以後單獨寫乙個帖子討論。

服務/看守程序

如果你不清楚服務和看守程序的概念,請看維基百科(這裡和這裡)。為了敘述方便,以下統稱服務。

由於c++開發的模組大部分是後台模組,經常會碰到服務的問題。編寫服務需要呼叫好幾個系統相關的api,導致了與作業系統的緊密耦合,很難用一套**搞定。因此比較好的辦法是抽象出乙個通用的服務外殼,然後把業務邏輯**作為動態庫掛載到它下面。這樣的話,至少保證了業務邏輯的**只需要一套;服務外殼的**雖然需要兩套(乙個用於windows、乙個用於posix),但他們是業務無關的,可以很方便地重用。

預設棧大小

不同的作業系統,棧的預設大小差別很大,從幾十kb(據說symbian只有12k,真摳門)到幾mb不等。因此你事先要打聽一下目標系統的預設棧大小,如果碰上像symbian這樣摳門的,可以考慮用編譯器選項調大。當然,養成「不在棧上定義大陣列/大物件」的好習慣也很重要,否則再大的棧也會被撐爆的。

看到這裡,可能有同學要問了,為什麼沒聊程序管理和多執行緒的話題?欲知後事如何,且聽下回分解。

C 的可移植性和跨平台開發 0 概述

今天聊聊c 的可移植性問題。如果你平時使用c 進行開發,並且你對c 的可移植性問題不是非常清楚,那麼我建議你看看這個系列。即使你目前沒有跨平台開發的需要,了解可移植性方面的知識對你還是很有幫助的。c 的可移植性這個話題很大,包括了編譯器 作業系統 硬體體系等很多方面,每乙個方面都有很多內容。鑑於本人...

C 的可移植性和跨平台開發 2 語法

目前還有相當一部分開發人員在使用老式編譯器幹活,這些老式編譯器可能對c 98支援不夠。因此,當你的 移植到這些老式的編譯器上時,可能會碰到一些稀奇古怪的問題 包括編譯出錯和執行時錯誤 下面這些注意事項有助於你繞過這些問題。強調一下,後面提到的好幾個條款都是通過迴避c 的新語法來保證移植性。如果你用的...

C 的可移植性和跨平台開發 2 語法

目前還有相當一部分開發人員在使用老式編譯器幹活,這些老式編譯器可能對c 98支援不夠。因此,當你的 移植到這些老式的編譯器上時,可能會碰到一些稀奇古怪的問題 包括編譯出錯和執行時錯誤 下面這些注意事項有助於你繞過這些問題。強調一下,後面提到的好幾個條款都是通過迴避c 的新語法來保證移植性。如果你用的...