出自我的blog 原文連結: http://finaldie.com/wordpress/?p=21
好吧, 看到標題你一定認為我犯了一個big mistake, 我沒有遵循include .h標準範式去編寫程式, 不過我還是想說說這裡面的好處
現在我們有一個需求, 想要編寫一套事件庫以便適應不同的平台(linux, freebsd … ), OK, 這裡有一個顯然的問題是我們需要一套抽象介面, 以便不同的平台都去遵循使用它們, 在不同平台下編譯可以使用相應的.c檔案, 但是如何在編譯期去找到不同的實現檔案那? 因為不同的實現檔案需要在編譯期指定好, 寫在Makefile裡做參數? 顯然不夠智能, 我們還是希望可以auto build. 於是我們想出了一套看似完美的方案, 為不同平台建立不同命名的標頭檔, 比如linux下使用 ev_epoll.h,
freebsd下使用ev_kqueue.h, 不過這兩個檔案內部使用完全相同的介面定義, 一般來講這沒什麼問題, 我們只需要在framework雷根據不同平台include不同的header即可~ . 不過這裡有個潛在的問題, 我們一旦修改了抽象介面定義, 不但要修改響應實現檔案(這不可避免), 還需要級聯的維護響應的headers, 這看起來很糟糕, 然後聰明的我們又想出來一個升級方案, 在這些不同平台的headers裡面統一include一個global header(包含抽象描述), 我們拿著這套方案感覺很nice~
, 不過我們一旦修改, 仍然不可避免的去要修改global header, 雖然代價已經很小了~
好了, 贅贅的說了一大堆, 開始進入正題, 我們能不能有什麼辦法去掉這個header, 因為這個header本質上沒有存在的價值, 外部並需要看到他, 多個它放在那會讓使用者頭大不已, 請出我們今天主角:”include .c”, 我們先瞭解下include, 其實它並不在乎include什麼東東, 只要文法正確即可~ , 那麼利用這個特性, 我們直接include .c(相應平台的具體實現檔案, 比如ev_epoll.c/ev_kqueue.c), 你可以理解為他們的代碼被copy paste到include的位置,
然後我們不需要任何標頭檔的依賴, 也不需要為修改介面而相應去修改一個根本沒有存在必要的header.
,
最後簡單說下編譯這樣檔案的過程, 因為我們已經include.c了, 所以我們在寫Makefile的時候就不需要再去把這個.c檔案填進去了, 否則容易出現各種聲明,變數不存在的error, 調用include .c的檔案會自己幫我們把它copy paste過去, 我們就不用操心了, 是不是很簡單
Have fun~