程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 再談C語言的模塊化設計

再談C語言的模塊化設計

編輯:C++入門知識

現代語言為了可以接近玩樂高積木的那樣直接組合現有的模塊,都對模塊化做了語言級別上的支持。我想這一點在軟件工程界也是逐步認識到的。C 語言實在是太老了。而它的晚輩 Go 就提供了 import 和 package 兩個新的關鍵字。

這也是我最為認可的方式。之前提到的方案只能說是對其拙劣的模擬。確認語言級的支持,恐怕也只能做到這一步了。

在項目實踐中,那個 USING 的方案我用了許多年,還算滿意。之前有過更為復雜“精巧”的方法,都被淘汰掉了。為什麼?因為每每引入新的概念,都增加了新成員的學習成本。因為幾乎每個人都有 C 語言經驗,但每個人的項目背景卻不同。接受新東西是有成本的。任何不是語言層面上的“必須”,都有值得商榷的地方。總有細節遭到質疑。為什麼不這樣,或許會更好?這是每個程序員說出或埋在心裡的問題。

那個 USING 的方案遠不完美,它只是足夠簡潔,可以讓程序員勉強接受而已。但其實還不夠簡潔。因為從邏輯表達上來說,它是多余的。一個模塊使用了另一個模塊,代碼上已經是自明的。從 C 語言的慣例上來說,只要 #include 了一個相關的 .h 文件,就證明它需要使用關聯的模塊。

光用宏的技巧很難只依靠一次 #include 就搞定正確的模塊初始化次序。因為 C 語言並沒有明顯的模塊概念。如果將每個子模塊都編譯為動態庫可能能一定的解決問題我曾經試過這種方案),但卻會引出別的問題。細粒度的動態庫局限性太大。

這兩天我結合這半年學習 Go 語言的體驗,又仔細考慮了一下這個問題。想到另一個解決方案。

如果我們能規范系統中子模塊 API 的命名規范,或許可以借助編譯器和相關工具來做一些 meta programming 的工作。

我們可以使用 objdump 來分析編譯好的 .o 文件。比如有一個模塊 foo ,實現在 foo.c 中。objdump -t 可以得到 .o 中引用以及導出的符號。

我們要求所有子模塊中的 C API 都遵守一致的命名規范,假設用馱峰命名的話,foo 模塊中的 Api 就看起來像這樣 fooApi 。objdump 的結果可以輕易的識別出規范內的引用的其它子模塊有哪些。然後生成一個類似之前提到的 USING 方法可以調用的初始化函數。自定義的模塊初始化函數可以統一命名為 fooInit 的形式,當這個初始化函數存在,則由自動生成的代碼調用一下即可。

整個過程可能比較繁雜,但很容易用 make 這樣的構建工具自動化進行。具體實現我就不列出了。或許不久會新開開源項目實踐一下。

原文鏈接:http://blog.codingnow.com/2011/04/module_initialization.html#more

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved