登泰山而小天下:Boost C++ Libraries 初體驗

說來有些慚愧,一直以 C++ 語言做為謀生工具的我,在使用了多年的 C++ 程式語言之後,最近終於與聞名遐邇的開源專案 Boost C++ Libraries(簡稱為 Boost)進行了第一次的親密接觸。在本文裡,將參照 Boost 官網的「Getting Started on Windows」文章,於 Windows 作業系統以及 Visual Studio 2005 程式編譯器的環境下,詳細介紹安裝及建置 Boost 的步驟,並且在最後使用 Boost.Thread 函式庫做為測試範例。

從前就常聽到其他人談論著 Boost 的優點,但是只要知道其中由上千個標頭檔以及數十個函式庫所組成,而且還需要以繁複的步驟手動建立函式庫的 .lib 檔案,很容易就會使初學者望而卻步。對於用慣了程式整合開發環境以及現成函式庫的我來說,Boost 簡直就像是一座美麗動人但又戒備森嚴的堡壘般令人不敢輕易接近。多年以後的現在,總算是鼓起了勇氣重新面對 Boost。花了些時間閱讀文件,然後按照指示一步步完成安裝建置之後,發現原來這些步驟比起從前已經簡化許多,函式庫的使用也不如想像中的困難!

One of the reasons for boost’s success has been the cross-pollination of ideas between diverse library projects.

Boost 是由一群功能獨立的函式庫所組合而成的集合體,其中涵蓋了許多熱門而經常使用的函式庫,以及比較冷門的特殊功能作用函式庫。所有的函式庫都包含在名為 boost 的 namespace 中,不僅能夠使各函式庫維持一致的使用風格,同時也得以避免命名衝突的問題。如官網中的 FAQ 所述,Boost 的成功正是由於不同功能函式庫之間的「交叉授粉」(cross-pollination) 作用所致;雖然其中多數函式庫都能夠分開獨立使用,但正是由於函式庫之間相互支援的功能以及介面,才使得 Boost 的開發者社群與使用者社群能夠蓬勃發展且欣欣向榮。

而經過千錘百鍊的 Boost,也獲得了 C++ Standards Committee 的認可,其中有部分的函式庫例如 Array、Bind、Tuple 與 Unordered 等等皆已納入 C++ Technical Report 1(簡稱為 TR1)的範疇之中,很快地將會在眾所矚目的 C++ 語言新版本中,正式將這些函式庫納入標準。

事不宜遲,讓我們開始進入 Boost 的奇妙領域吧!

首先,於官網下載 Boost C++ Libraries 檔案包,目前最新的版本是於 2008 年 8 月 12 日發佈的 1.36 版。官網提供了多種不同壓縮格式的檔案包,建議下載以 7-Zip 包裝的 boost_1_36_0.7z 版本,檔案大小僅有 ZIP 版本的 50% 而已。下載完成後,直接執行檔案解壓縮,就會生成一個新的目錄 boost_1_36_0

「奇怪,怎麼看來看去都只有 .hpp 的標頭檔?那些 .cpp 跑到哪裡去了?」Boost 與其他開源專案最關鍵的不同之處,就是在於多數 Boost 中的函式庫,都是以「僅有標頭檔」(header-only) 的形式存在;也就是說,在使用多數的 Boost 函式庫時,只需要 #include 相對應的 .hpp 檔案,不需要額外連結 .lib 檔案就能夠快快樂樂地撰寫程式。Boost 之所以能夠達到這種令人讚嘆的神妙境界,主要歸功於 Template Metaprogramming 技術的強大威力,因此使 Boost 能夠在編譯時期動態生成所需的程式碼。

雖然多數 Boost 函式庫可以直接使用標頭檔,但是某些 Boost 函式庫例如 FileSystem、IOStream 與 Thread 等等,就必須要建置並且連結 .lib 檔案才能夠使用。而在下載回來的資料包之中,只有包含原始碼檔案,所以我們需要自己進行 .lib 檔案的建置工作。為了建置所需的函式庫,必須使用 bjam 這個工具。再次於官網下載 boost-jam-3.1.16-1-ntx86.zip,解壓縮後將其中的 bjam.exe 移至 boost_1_36_0 目錄下,接著開啟「Visual Studio 2005 命令提示字元」,更換目錄至 boost_1_36_0 後,執行以下指令然後耐心等待(依電腦配備等級不同,約需要數十分鐘的建置時間):

bjam --build-dir=".\build" --toolset=msvc stage

其中 –build-dir 參數指定的是建置函式庫的輸出目錄,在此設定為 .\build,就是在 boost_1_36_0 目錄下產生一個新的 build 目錄;而 –toolset 則是指定用來建置函式庫的工具,設定為 msvc 也就是使用 Microsoft Visual Studio 的編譯器執行建置;最後的 stage 參數則是一個特殊的建置目標,在函式庫建置完畢之後,會將所有的 .lib 與 .dll 檔案複製一份到 boost_1_36_0\stage\lib\ 目錄當中。

在上述的預設指令中,只會建置出 Release 組態的函式庫,如果想要建置出包含 Debug 組態在內的所有函式庫組態,可以在指令中加上 –build-type=complete 參數;而如果不想花費許多時間建立所有的函式庫,只想要建立其中某個函式庫,就可以使用 –with 參數後面接上函式庫的名稱。以單獨建置 Boost.Thread 為例:

bjam --with-thread --build-dir=".\build" --build-type=complete --toolset=msvc stage

如果不確定有哪些函式庫可以使用 bjam 建置,可以使用 –show-libraries 參數列出所有可建置的函式庫:

bjam --show-libraries

接下來,就創建一個專案正式和 Boost 說聲 Hello World 吧!

由於範例中所使用的 Boost.Thread 函式庫,相依於 Boost.DateTime 處理與時間相關的功能,所以首先要按照之前的步驟將 Boost.DateTime 建置起來:

bjam --with-date_time --build-dir=".\build" --build-type=complete --toolset=msvc stage

然後在 Visual Studio 2005 中,創建一個「Win32 主控台應用程式」的空專案,新增一個 .cpp 檔案並且填入以下程式碼:

#include < boost/thread/thread.hpp >
#include < iostream >

void helloworld()
{
    std::cout << "Hello World!" << std::endl;
}

void main()
{
    boost::thread thrd(&helloworld);
    thrd.join();
}

將專案屬性中的「其他 Include 目錄」設定為 boost_1_36_0 所在的目錄,「其他程式庫目錄」則設定為 boost_1_36_0\stage\lib;在設定時不需要明確指定要連結的 .lib 檔案名稱,Boost 會自動連結 (Automatic linking) 到正確的函式庫版本。以上步驟完成後,按下建置方案然後執行,第一個 Boost.Thread 的 Hello World 程式就誕生囉!

另外,如果將 Boost.Thread 搭配 Boost.Bind 函式庫一起服用,就能夠更便利地傳入 Thread Function 所需的參數值。因為 Boost.Bind 不需連結 .lib 檔案,所以只要 #include 指定 boost/bind.hpp 檔案就可以立即使用:

#include < boost/thread/thread.hpp >
#include < boost/bind.hpp >
#include < iostream >

void helloworld(const char* who)
{
    std::cout << who << ": "Hello World!"" << std::endl;
}

void main()
{
    boost::thread thrd(boost::bind(&helloworld, "MonkeyPotion"));
    thrd.join();
}

開始使用 Boost,就是這麼輕鬆簡單!

為了取得更多關於 Boost 的深入知識,除了官方文件以外,我也嘗試著在網路上搜尋相關的教學文章與使用心得。結果一如預期,網路上關於 Boost 的中文資訊仍然相當稀少,而其中繁體中文的資訊更是少之又少。「Boost 中文站」是我目前找到內容最為豐富的 Boost 主題網站,其中的「C++ Boost Thread 编程指南」寫得相當出色,是一篇值得仔細閱讀的好文章。

目前為止,我僅僅接觸了這座龐大城堡中的一項 Boost.Thread 函式庫,就已經深深感受到 Boost C++ Libraries 的驚人威力。登上巨人的肩膀,才會知道世界有多遼闊,而自己又有多渺小。從現在開始,我會抱持著滿滿的學習熱誠與好奇心,努力探索 Boost 領域的知識,請幫我推薦些實用有趣的 Boost 函式庫吧!

13 Replies to “登泰山而小天下:Boost C++ Libraries 初體驗”

  1. 這東西我有一段時間在使用它。給我感覺是:非常好用!讓我對C++更加一層的瞭解。
    可惜在於公司中只有我一個人會用,也基於別人的維護性考量,也減少去使用它。

    我只用過smart_ptr、any、variant、tuple、bind、Lambda、Function、
    Signals、Pool…等。

    在使用這工具的過程,我覺得最難的地方在於編譯器的那關!
    只要不小心使用工具錯誤,編譯器所告知的錯誤訊息可是讓人看不懂的。
    並不是以往的「尚未定」或「重複定義」的簡單錯誤訊息。
    所以對新手且對template不熟的人來說,相當超級難入手。

    我也提供一些資訊吧~如果懶得去bulid lib的話,到這網站下載吧!

    網址:http://www.boostpro.com/products/free

    也感謝一些提供boost的相關資訊。

  2. 剛好我幾天也正在編 boost 1.36,

    關於 bjam 的 targets 參數(最後那個),
    我通常都是用 “install” 而非 boost 官方建置文件中所提到的 “stage”
    “install” 與 “stage” 的主要差別在於,
    — “install” : 將 header 檔與編好的 lib, dll 檔放到指定的資料夾中
    — “stage” : 將編好的 lib, dll 檔放到 ./stage 資料夾中

    “install” 與 “stage” 的詳細說明,以及相關的參數設定,官方網頁上不容易找到資訊,
    不過可以在 boost 解開後的目錄下,輸入 “bjam –help” 來查詢 (所以算是隱藏密技 XD)
    由於 help 資訊很多,所以要捲到第一頁才看得到。

    “install” 最常用的搭配參數就是 “–prefix=prefix_dir”,
    用來指定要把 header 跟 lib 全部丟到哪個資料夾去。
    我一開始都很認真的指定,後來也都懶得設了,直接用預設的值: “C:\Boost”
    (unix 下為 /usr/local/)

    因此我編譯 boost 的指令為
    $> bjam –build-type=complete –toolset=msvc install
    編譯完 C: 底下會出現一個 Boost 資料夾,建置專案所需要的就通通都在這裡面了,
    把這整個資料夾壓縮起來,看是要丟到其他電腦,或是丟上版本控制系統,都很方便 ^_^

  3. @vamper:
    好東西就是要好好的用力推廣才行啊!(握拳)

    以我最常使用的 Visual Studio 編譯器來說,一直以來都對於 Template Programming 錯誤訊息的支援度很差,這也是使用 Template 相關的程式技術時最大的困擾。只希望在 C++0x 標準正式釋出以後,新版本的 Visual Studio 能夠為程式設計者提供更加完善且具有意義的編譯錯誤資訊。

    感謝提供 BoostPro 網站的相關訊息~

    @yuxioz:
    讚!果然是專業的!

    我嘗試了一下用 install 單獨建置 boost.thread,如果要把函式庫打包丟到其他電腦上使用的話,的確是十分便利呢。不過我檢查了 include 目錄中的檔案後,發現檔案數量幾乎快等同於 Boost 全部的標頭檔了。 囧rz

    感謝你的專業補充說明~ XD

    @fr3@K:
    謝謝,期望能見到你寫更多關於 Boost 主題的文章。

  4. @C++編程愛好者:
    你好,

    太棒了!很開心能夠多認識專業且具深度的 C++/Boost 網站,往後必定會多多拜訪學習。

    感謝您的來訪。 ^^

  5. 一直有學習Boost的想法,無奈也是一直未能下定決心開始研究它。看到了這篇文章後終於下定決心了。謝過大大先^^

  6. @西瓜玩偶:
    Boost 函式庫提供的功能模組相當廣泛,我想若你有相關的功能需求,再去學習取用該功能模組即可。

Leave a Reply