NET組件和COM組件之間的相互操作
- 摘要:我們不但可以在.NET組件中調(diào)用COM組件,同時也可以在COM組件中正常的調(diào)用.NET組件。
- 標(biāo)簽:.net
-
.NET組件可以分為兩大類:共享的.NET組件和私有的.NET組件。
共享的.NET組件需要通過標(biāo)準公開關(guān)鍵字密碼技術(shù)來保證自身的唯一性,在這一點上面比較類似于COM的全球唯一ID號碼GUID。但是,我們在可能的情況下應(yīng)當(dāng)盡量避免使用共享的.NET組件,因為這樣將會有可能再一次的陷入目前在視窗系統(tǒng)下長期困擾開發(fā)人員的“DLL地獄”。
私有的.NET組件是我們將會經(jīng)常使用的.NET組件方式,在這種方式之下,我們發(fā)布.NET組件需要做的只是簡單的進行拷貝操作就可以了,仿佛回到了遠古的DOS時代了,在也不必關(guān)心紛繁復(fù)雜的系統(tǒng)注冊表了,也不必擔(dān)心DLL的版本被覆蓋等等的問題了。
而COM組件是微軟曾經(jīng)力推了很多年的一種代碼復(fù)用的技術(shù)框架,在這些年里也得到了極大的發(fā)展和應(yīng)用,但它的弊端卻也日益明顯,我們不得不面對眾多的COM組件之間的版本控制和令人恐怖的DLL地獄,還有注冊表、GUID等等。在我們安裝一個軟件的同時,也帶來了大量的我們所未知的版本繁多的COM組件到我們的操作系統(tǒng)中。
但是,COM組件的技術(shù)優(yōu)勢也是明顯的,在很大的程度上實現(xiàn)了Windows平臺下的代碼復(fù)用,所以我們才會提出這樣的一個話題,如何才能在.NET技術(shù)日臻成熟的情況下,保護和利用已經(jīng)存在的大量的采用COM技術(shù)的軟件和產(chǎn)品呢?
下面我們就探討一下,如何實現(xiàn).NET組件和COM組件之間的相會調(diào)用和操作。
首先,我們來看看在現(xiàn)有的COM組件中如何調(diào)用.NET編寫的組件吧:
在這里我們使用C#編寫一個最簡單的組件,僅僅實現(xiàn)返回一個字符串,詳細的代碼如下:
在上面的.NET組件當(dāng)中我們實現(xiàn)了一個類成員:say。他的用途是簡單的返回一段字符串。
切換到MS-DOS命令行下面,運行:
C:\>csc /t:library /out ClassLibrary1.DLLClassLibrary1.cs
上面的編譯器參數(shù)/t:library 告訴C#編譯器我們現(xiàn)在是在建立一個庫應(yīng)用程序。這樣,我們就得到了一個名稱為ClassLibrary1.DLL的.NET組件了。
但是想要在現(xiàn)有的COM組件中使用這個組件,我們還有進行如下步驟:
切換到MS-DOS命令行下面,運行:
C:\>regasm out ClassLibrary1.DLL /regfile:ClassLibrary1.reg
上面的命令行是注冊我們的.NET組件,并且產(chǎn)生了一個備用的注冊表文件。大家一定會記得在以前我們的win9x/NT/2000下面注冊COM組件使用的命令是:
regsvr32 c:\test.dll
在.NET下面,注冊.NET組件就需要上面的regasm命令了,值得注意的是,這個方法僅僅是為了可供COM組件來調(diào)用,.NET本身之間相互調(diào)用組件是不需要任何注冊的!
還沒有結(jié)束呢,接下來我們需要:
切換到MS-DOS命令行下面,運行:
C:\>tlbExp ClassLibrary1.dll /out:ClassLibrary1.tlb
上面的命令行表示將會產(chǎn)生一個.NET組件的類型庫,目的是為了我們在COM組件中進行提前綁定操作。
好了,接下來我們就可以在自己的基于目前COM技術(shù)的代碼中方便的使用上面我們使用C#編寫的.NET組件了。在這里,我們使用VB6.0編寫一個小小的測試代碼,在開始之前我們需要在VB的集成環(huán)境中使用菜單中的“引用”選項,選擇我們剛才產(chǎn)生的類型庫文件ClassLibrary1.tlb。
VB測試的代碼如下:
Private Sub Form_Load()
Dim test As New ClassLibrary1.hello
Dim str As String
str = test.say("dddd")
MsgBox str
End Sub
接下來,我們就來看看,如何在.NET組件中使用目前存在的COM組件吧。
對于.NET來講,使用COM組件要想對簡單一些。.NET在設(shè)計之初就考慮到了如何方便的利用現(xiàn)有的各種技術(shù)資源,這也是微軟的一貫作風(fēng),.NET的強大之處也可見一斑。.NET提供了大量的類庫來方便的實現(xiàn)同COM的相互操作,其中很重要的一個名稱空間就是:System.Runtime.InteropServices。通過這個名稱空間的名字我們也可以從字面上看出,“互操作服務(wù)”。System.Runtime.InteropServices這個名稱空間提供了一系列的類來對COM對象進行操作。
下面的例子中,我們來調(diào)用一下系統(tǒng)自帶的Win32函數(shù)MessageBoxA,這個函數(shù)位于系統(tǒng)的COM組件user32.dll當(dāng)中,我們調(diào)用的代碼如下:
using System;
using System.Runtime.InteropServices;
class Test
{
[DllImport("user32.dll")]
public static extern int MessageBoxA(inthWnd,string strMsg,string strCaption,intnType);
public static void Main()
{
int myMsg;
myMsg=MessageBoxA(0,"Hello!","test",0);
}
}
切換到MS-DOS命令行下面,運行:
C:\>csc Test.cs
編譯完畢我們的C#應(yīng)用程序之后,直接運行就可以看到對話框了!
需要注意的是,在調(diào)用COM組件之前,我們需要在.NET程序中引用名稱空間:System.Runtime.InteropServices。因為我們需要使用這個名稱空間所提供的一個方法:DllImport。
怎么樣,在.NET中使用COM組件是非常的方便的吧。上面是我們調(diào)用的系統(tǒng)本身自帶的DLL組件,同樣的,也可以使用這種方法來調(diào)用我們自己使用VB/VC編寫的COM組件。
好了,我們已經(jīng)探討完了如何在.NET和COM之間相互操作了,我們也很顯然的看到了.NET技術(shù)的強大,現(xiàn)在越早掌握.NET技術(shù)就會在未來越容易的占領(lǐng)領(lǐng)先的位置,讓我們共同努力掌握強大的.NET平臺技術(shù)吧。