用VC進行COM編程所必須掌握的理論知識

字號:

這篇文章是給初學者看的,盡量寫得比較通俗易懂,并且盡量避免編程細節(jié)。完全是根據我自己的學習體會寫的,其中若有技術上的錯誤之處,請大家多多指正。
    一、為什么要用COM
     軟件工程發(fā)展到今天,從一開始的結構化編程,到面向對象編程,再到現在的COM編程,目標只有一個,就是希望軟件能象積方塊一樣是累起來的,是組裝起來的,而不是一點點編出來的。結構化編程是函數塊的形式,通過把一個軟件劃分成許多模塊,每個模塊完成各自不同的功能,盡量做到高內聚低藕合,這已經是一個很好的開始,我們可以把不同的模塊分給不同的人去做,然后合到一塊,這已經有了組裝的概念了。軟件工程的核心就是要模塊化,最理想的情況就是100%內聚0%藕合。整個軟件的發(fā)展也都是朝著這個方向走的。結構化編程方式只是一個開始。下一步就出現了面向對象編程,它相對于面向功能的結構化方式是一個巨大的進步。我們知道整個自然界都是由各種各樣不同的事物組成的,事物之間存在著復雜的千絲萬縷的關系,而正是靠著事物之間的聯(lián)系、交互作用,我們的世界才是有生命力的才是活動的。我們可以認為在自然界中事物做為一個概念,它是穩(wěn)定的不變的,而事物之間的聯(lián)系是多變的、運動的。事物應該是這個世界的本質所在。面向對象的著眼點就是事物,就是這種穩(wěn)定的概念。每個事物都有其固有的屬性,都有其固有的行為,這些都是事物本身所固有的東西,而面向對象的方法就是描述出這種穩(wěn)定的東西。而面向功能的模塊化方法它的著眼點是事物之間的聯(lián)系,它眼中看不到事物的概念它只注重功能,我們平常在劃分模塊的時侯有沒有想過這個函數與哪些對象有關呢?很少有人這么想,一個函數它實現一種功能,這個功能必定與某些事物想聯(lián)系,我們沒有去掌握事物本身而只考慮事物之間是怎么相互作用而完成一個功能的。說白了,這叫本末倒置,也叫急功近利,因為不是我們智慧不夠,只是因為我們沒有多想一步。面向功能的結構化方法因為它注意的只是事物之間的聯(lián)系,而聯(lián)系是多變的,事物本身可能不會發(fā)生大的變化,而聯(lián)系則是很有可能發(fā)生改變的,聯(lián)系一變,那就是另一個世界了,那就是另一種功能了。如果我們用面向對象的方法,我們就可以以不變應萬變,只要事先把事物用類描述好,我們要改變的只是把這些類聯(lián)系起來的方法,只是重新使用我們的類庫,而面向過程的方法因為它構造的是一個不穩(wěn)定的世界,所以一點小小的變化也可能導致整個系統(tǒng)都要改變。然而面向對象方法仍然有問題,問題在于重用的方法。搭積木式的軟件構造方法的基礎是有許許多多各種各樣的可重用的部件、模塊。我們首先想到的是類庫,因為我們用面向對象的方法產生的直接結果就是許多的類。但類庫的重用是基于源碼的方式,這是它的重大缺陷。首先它限制了編程語言,你的類庫總是用一種語言寫的吧,那你就不能拿到別的語言里用了。其次你每次都必須重新編譯,只有編譯了才能與你自己的代碼結合在一起生成可執(zhí)行文件。在開發(fā)時這倒沒什么,關鍵在于開發(fā)完成后,你的EXE都已經生成好了,如果這時侯你的類庫提供廠商告訴你他們又做好了一個新的類庫,功能更強大速度更快,而你為之心動又想把這新版的類庫用到你自己的程序中,那你就必須重新編譯、重新調試!這離我們理想的積木式軟件構造方法還有一定差距,在我們的設想里希望把一個模塊拿出來再換一個新的模塊是非常方便的事,可是現在不但要重新編譯,還要冒著很大的風險,因為你可能要重新改變你自己的代碼。另一種重用方式很自然地就想到了是DLL的方式。Windows里到處是DLL,它是Windows 的基礎,但DLL也有它自己的缺點??偨Y一下它至少有四點不足。(1)函數重名問題。DLL里是一個一個的函數,我們通過函數名來調用函數,那如果兩個DLL里有重名的函數怎么辦?(2)各編譯器對C++函數的名稱修飾不兼容問題。對于C++函數,編譯器要根據函數的參數信息為它生成修飾名,DLL庫里存的就是這個修飾名,但是不同的編譯器產生修飾的方法不一樣,所以你在VC 里編寫的DLL在BC里就可以用不了。不過也可以用extern “C“;來強調使用標準的C函數特性,關閉修飾功能,但這樣也喪失了C++的重載多態(tài)性功能。(3)路徑問題。放在自己的目錄下面,別人的程序就找不到,放在系統(tǒng)目錄下,就可能有重名的問題。而真正的組件應該可以放在任何地方甚至可以不在本機,用戶根本不需考慮這個問題。(4)DLL與EXE的依賴問題。我們一般都是用隱式連接的方式,就是編程的時侯指明用什么DLL,這種方式很簡單,它在編譯時就把EXE與DLL綁在一起了。如果DLL發(fā)行了一個新版本,我們很有必要重新鏈接一次,因為DLL里面函數的地址可能已經發(fā)生了改變。DLL的缺點就是COM的優(yōu)點。首先我們要先把握住一點,COM和DLL一樣都是基于二進制的代碼重用,所以它不存在類庫重用時的問題。另一個關鍵點是,COM本身也是DLL,既使是ActiveX控件.ocx它實際上也是DLL,所以說DLL在還是有重用上有很大的優(yōu)勢,只不過我們通過制訂復雜的COM協(xié)議,通COM本身的機制改變了重用的方法,以一種新的方法來利用DLL,來克服DLL本身所固有的缺陷,從而實現更高一級的重用方法。COM沒有重名問題,因為根本不是通過函數名來調用函數,而是通過虛函數表,自然也不會有函數名修飾的問題。路徑問題也不復存在,因為是通過查注冊表來找組件的,放在什么地方都可以,即使在別的機器上也可以。也不用考慮和EXE的依賴關系了,它們二者之間是松散的結合在一起,可以輕松的換上組件的一個新版本,而應用程序混然不覺。