什麼是跨平台?
舉個簡單的例子,就是你寫的程序在windows下可以運行,在linux下經過簡單的處理後也能運行。
標准定義:泛指程序語言、軟件或硬件設備可以在多種作業系統或不同硬件架構的電腦上運作。
為什麼要關注跨平台?
其實,如果你只希望你的程序在特定的軟硬件環境下運行的話,的確可以不用關注和考慮跨平台。但是,這樣的程序不具有很好的可移植性,一旦有了在新的環境或者操作系統上運行的需求,則往往需要花費大量的勞力進行修改和移植,甚至整個軟件系統都重新設計,這樣的代價是很大的、很不劃算的。
因此,跨平台是軟件開發中一個重要的概念,即希望開發出來的軟件,既不依賴於操作系統,也不信賴硬件環境,這樣的軟件可以得到更加廣泛的應用。
那麼,是什麼阻礙著我們的軟件實現跨平台?
MFC應用程序能在linux下跑麼? winSocket網絡通信程序能運行在Unix下嗎? 使用Access數據庫記錄系統參數的應用程序具備可移植性麼? 使用DirectX庫開發的多媒體應用能否移植到其他系統呢?
顯然,以上各種應用都不具備跨平台的性能,原因如下:
MFC是微軟提供的一種應用程序框架,該框架與windows操作系統有著緊密的耦合;winSocket是windows提供的一系列網絡編程API,在其他操作系統下有著不同的API接口;Access數據庫是基於Windows的桌面關系數據庫管理系統,本身不具備跨平台性能,故針對它開發的應用程序才隨之喪失了跨平台的特性;而DirectX是一種應用程序接口(也可以說是第三方庫),它可以基於windows為平台的游戲或多媒體程序獲得更高的執行效率。
由上述例子可以看出,是什麼阻礙著我們跨平台?
(1) 非跨平台的應用程序框架 —— 例如:MFC,WinForm
(2) 特定操作系統的API —— 例如:windows API
(3) 非跨平台的第三方軟件 —— 例如:access數據庫
(4) 非跨平台的第三方庫 —— 例如:DirectX
(5) 程序中出現非跨平台的語句 —— 例如:#prgram once,TRACE,Sleep,CString
到此,我們似乎已經找到了跨平台的思路了,對!只要我們能夠避免阻礙我們跨平台的因素,我們就能夠實現我們軟件的跨平台特性,那麼,跨平台的道路上,我們有著哪些選擇呢?
(1) 應用程序框架:
如果我們開發的僅僅是控制台(console)工程,而不需要華麗的或者可視化的界面,那麼我們就可以不用選擇應用程序框架了;如果我們需要開發可視化的客戶端,可以使用跨平台的Qt或者wxWidgets,其中Qt是一個跨平台的C++圖形用戶界面應用程序框架。它提供給應用程序開發者建立藝術級的圖形用戶界面所需的各種功能;而wxWidgets也是一個開源的跨平台的C++構架庫,提供了GUI圖形用戶界面)以及其它工具。
(2) 操作系統API
目前還沒有統一的API是不同的操作系統同時都支持的,那麼,我們需要使用操作系統的API時,怎麼辦呢?其實,仔細想想你就能明白,操作系統的API只不過是一系列的函數,提供對文件讀寫、網絡收發、數據庫訪問、內存管理、進程線程等應用的封裝好的方法罷了。其實,我們要實現對應的應用,其實並不一定要使用操作系統提供的API嘛,我們完全可以使用第三方庫來實現這些操作功能!例如,強大的boost庫就提供了針對上述應用的很全面的操作接口,如 Filesystem模塊提供了對文件讀寫的一系列操作,如 Asio模塊提供了對網絡通信編程的良好封裝,如Thread 模塊提供了對創建銷毀進程線程的良好實現,Smart Ptr模塊提供的智能指針實現了內存的良好管理等等。有了這些第3方庫,再加上STL提供的一些容器和算法,還有什麼應用我們必須使用操作系統API才能夠實現?
(3) 第三方軟件
其實,第三方軟件並不是特別棘手的問題。我們其實很容易找到跨平台的第三方軟件替換掉那些不跨平台的軟件,雖然偶爾會付出一些小小的代價。像數據庫,其實有很多數據庫系統都是跨平台的,例如mySQL,PostgresSQL等,我們大可選擇這些跨平台的數據庫以防止我們的跨平台之路被阻礙。
(4) 第三方庫
這個上面已經提到,其實現在存在很多很好的跨平台的第三方庫,例如boost庫,OpenGL庫,rtp應用方面有jrtplib庫,網絡編程方面有ACE庫,等等。對於特定的應用,我相信,你總可以找到一些對應的跨平台的庫來滿足你的需求。
(5) 編程語句
同樣,我們需要使用一些跨平台的語句來代替一些非跨平台的語句。例如 #prgram once,我們可以使用下面這樣的語句來替換。
#ifndef XXXX_H_
#define XXXX_H_
……
#endif //XXXX_H_
當然,對於實在沒有什麼替換的語句,我們可以使用另外一種方案,那就是條件編譯,形式如下:
#if defined WINDOWS
Sleep(1000)
#elif LINUX
sleep(1000*1000)
#else
……
#endif
說到這裡,其實,跨平台的基本概念和基本知識我想大家也應該都清楚了。但其實真正想寫好跨平台的程序,其實還是任重道遠的,因為有很多其他的細節因素需要在實戰中慢慢積累,下面我就舉幾個常見的問題作為本文的結尾吧!
1. 文件與目錄的大小寫以及路徑分隔符的差別問題
windows下不區分大小寫,路徑分隔符一般使用"\";linux下區分大小寫,路徑分隔符使用"/"。在程序中操作文件和目錄的路徑時這一點要注意。
2. linux下和windows下文件擴展名不同
例如,linux下沒有exe和dll程序,dll在linux下對應的是.o文件,所以在程序中不要判定系統中是否存在某某exe程序。
3. 在每一個.h文件後面都多加上一行,否則在linux下編譯時會有警告
4. C++中基本類型的大小占用的字節數)會隨著CPU字長的變化而變化。所以,假如你要表示一個int占用的字節數,千萬不要直接寫“4”,而應該使用sizeof()函數
5. 內存對齊
出於CPU處理上的性能考慮,結構體中的數據不是緊挨著的,而是要空開一些間隔。這樣的話,結構體中每個數據的地址正好都是某個字長的整數倍。由於C++標准中沒有定義內存對齊的細節,因此,你的代碼也不能依賴對齊的細節。凡是計算結構體大小的地方,都應該老老實實寫上sizeof()。
……
好了,就說這麼多了,希望我在跨平台軟件編程方面的心得能夠對你有所幫助,有任何其他疑問,歡迎來信交流:[email protected]
本文出自 “對影成三人” 博客,請務必保留此出處http://ticktick.blog.51cto.com/823160/289618