.net framework的產生已經有兩年多的時間了,有不少公司開始采用.net開發應用軟件。但是很多公司在多年的項目應用中,開發了很多com、dcom組件,現在采用.net開發組件,使這些組件成為了遺留代碼。由于在開發com組件時投入了大量的人力、財力,如何在.net環境下重用這些com組件就顯得更有意義,本文將介紹使這些com組件“起死回生”的方法。
.net支持運行時通過com、com+、本地winapi調用與未管制代碼的雙向互操作性,bcl為此提供了一套類和屬性,包括受管制對象生存期的精確控制等。要實現互操作性,必須首先引入.net framework的 system.runtime.interopservices命名空間。c#的語法為:
using system.runtime.interopservices;
而vb.net的語法為:
import system.runtime.interopservices
.net訪問api
.net允許c#訪問未管制的dll的函數。如要調用windows user32.dll的messagebox函數:
int messagebox(hwnd hwnd,lpctstr lptext, lpctstr lpcaption,uint utype)
可以聲明一個具有dllimport屬性的static extern方法:
using system.runtime.interopservices;
[dllimport(“user32.dll”)]
static ertern int messagebox(int hwnd,string text,string caption,int type);
然后在代碼里面直接調用就可以了。這里要注意在調用返回字符串的api中使用stringbuilder對象。
.net訪問com組件
從.net調用com組件比較容易,只要使用tlbimp.exe產生com的裝配形式的warpclass,然后在.net項目中調用即可。
注意com的類型信息通過type library文件描述,.net裝配件是自描述的。tlbimp的作用是從com組件及其類型信息中產生自描述的裝配件。由于vb是進行com組件開發最簡單的語言,所以我們以一個簡單的vb com組件來說明。
1.編寫vb組件
vb組件原碼(文件名coaccount.cls)如下:
private m_balance as integer
’組件的私有成員變量
public sub deposit(sum as integer)
’存錢的方法
m_balance = m_balance + sum
end sub
public property get balance() as integer
’屬性balance訪問成員變量m_balance
balance = m_balance
end property
將上述代碼編譯生成coaccount.dll。
2. 產生.net可訪問的包裝類(assembly),使用tlbimp.exe產生.net裝配件。
tlbimp /out:netaccount.dll coaccount.dll
3.在.net代碼中訪問
.net代碼只需引用coaccount.dll,就可以像訪問.net的裝配件一樣訪問com組件。
將.net組件轉化為com組件
因為.net裝配件開發效率較高,先在.net環境下開發裝配件,然后轉化為com組件,由vb、asp等調用,可以加快開發進度。下面我們用一個例子簡單闡述一下整個過程。步驟如下:
1.定義接口
com是通過拋出接口讓外部應用調用的,每個接口、組件都有一個guid,在.net中開發com組件也不例外。
[guid(“18e2bcaf-f4b5-4031-8f84-fcfb1dc04877”)] //接口guid
public interface iaccount
//定義接口iaccount
{ [dispid(1)]
//每個方法或屬性都具有dispid屬性,是為了讓vbscript等腳本語言調用
void deposit(int num);
//方法,實現存錢的功能
[dispid(2)]
int balance
//屬性,查看當前的賬戶余額,只讀。請注意.net下屬性的定義方法
{ get; }
}
2.實現接口的派生類
[guid(“9e5e5fb2-219d-4ee7-ab27-e4dbed8e123e”), //組件的guid
classinterface(classinterfacetype.none)]
//指明組件的調用方式,支持后期綁定
public class netaccount:iaccount
//實現接口派生類,注意派生類要實現接口的所有方法。
{ private int balance;
//組件的私有成員變量(在.net中稱為域(field))
public netaccount()
//構造函數,初始化成員變量
{ balance=10; }
public void deposit(int num)
//實現存錢方法。
{ balance+=num; }
public int balance
//實現balance屬性,通過它訪問成員變量
{ get
{ return balance; }
}
}
3.將.net私有裝配件轉化成公有裝配件
.net下對裝配件的調用,實際上是拷貝到調用應用程序的本地目錄,稱為私有裝配件。要轉化為com組件,首先要轉化為公有裝配件,也就是放到gac里。
(1) 創建強名字
為了使com對象能夠被外部對象調用,類庫組合必須有一個強名字。創建強名字需要用到sn.exe,語法為:sn -k account.snk, 然后將強名字拷貝到debug目錄下。打開assemblyinfo.cs,并修改下面一行的內容:
[assembly: assemblykeyfile(@“account.snk”)]
(2) 將裝配件轉入gac
編譯項目文件產生netaccount.dll文件,使用gacutil.exe裝入gac:
gacutil -i netaccount.dll
(3) 注冊裝配件
在注冊表里面注冊裝配件,允許com組件的客戶調用,也可以生成注冊表文件,以備將來調用。
regasm netaccount.dll
執行上述語句,則裝配件可以被腳本語言調用。
(4) 導出類型庫
為了可以在vb里面使用組件,必須使用tlbexp.exe導出com類型庫。
tlbexp /out:netaccount.tlb netaccount.dll
經過上面的工作,就將一個.net裝配件轉化為com組件。需要注意的是:在com中調用.net對象需要具備以下條件:
● 類必須是public性質;
● 特性、方法和事件必須是public性質的;
● 特性和方法必須在類接口中定義;
● 事件必須在事件接口中定義。
(計算機世界報 第43期 c17、c18)
新聞熱點
疑難解答
圖片精選