實戰開發經驗:是什麼阻礙了咱們跨平臺

什麼是跨平臺?linux


舉個簡單的例子,就是你寫的程序在windows下能夠運行,在linux下通過簡單的處理後也能運行。算法


標準定義:泛指程序語言、軟件或硬件設備能夠在多種做業系統或不一樣硬件架構的電腦上運做。數據庫


爲何要關注跨平臺?編程


其實,若是你只但願你的程序在特定的軟硬件環境下運行的話,的確能夠不用關注和考慮跨平臺。可是,這樣的程序不具備很好的可移植性,一旦有了在新的環境或者操做系統上運行的需求,則每每須要花費大量的勞力進行修改和移植,甚至整個軟件系統都從新設計,這樣的代價是很大的、很不划算的。windows


所以,跨平臺是軟件開發中一個重要的概念,即但願開發出來的軟件,既不依賴於操做系統,也不信賴硬件環境,這樣的軟件能夠獲得更加普遍的應用。網絡


那麼,是什麼阻礙着咱們的軟件實現跨平臺?架構


MFC應用程序能在linux下跑麼? winSocket網絡通訊程序能運行在Unix下嗎? 使用Access數據庫記錄系統參數的應用程序具有可移植性麼? 使用DirectX庫開發的多媒體應用可否移植到其餘系統呢?框架


顯然,以上各類應用都不具有跨平臺的性能,緣由以下:ide


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. 使用sizeof來肯定類型的大小


C++中基本類型的大小(佔用的字節數)會隨着CPU字長的變化而變化。因此,假如你要表示一個int佔用的字節數,千萬不要直接寫"4",而應該使用sizeof()函數

    

5. 內存對齊


出於CPU處理上的性能考慮,結構體中的數據不是緊挨着的,而是要空開一些間隔。這樣的話,結構體中每一個數據的地址正好都是某個字長的整數倍。因爲C++標準中沒有定義內存對齊的細節,所以,你的代碼也不能依賴對齊的細節。凡是計算結構體大小的地方,都應該老老實實寫上sizeof()。


好了,就說這麼多了,但願我在跨平臺軟件編程方面的心得可以對你有所幫助,有任何其餘疑問,歡迎來信交流:lujun_hust@gmail.com,或者關注個人新浪微博 @盧_俊 獲取最新的文章和資訊。

相關文章
相關標籤/搜索