在非託管環境下使用託管環境下的程序集(轉)

 

在非託管環境下使用託管環境下的程序集(轉)

轉自:http://www.wwit.cn/www/down/Article.Asp?id=790

2


        自.Net問世以後,我們習慣的VC++,VB編程模式有了很大的變換,託管與非託管的概念也不斷映入程序員們的眼簾,可以說.NET正逐步成爲編程的主流語言和平臺之一。今天不與大家討論誰主沉浮,也不發表慷慨激揚的陳詞,到底這種編程模式(
或者說是方式)好與否,由所有的程序員們在實踐中去探討證實吧!今天學習中遇到了託管與非託管環境下程序集的相互調用問題,覺得應該和大家分享一下,無論多麼的簡單,我只是希望在開發模式日新月異的時代,大家一定要抓住事物的變化特徵。下面和大家分享一下!
        微軟的.NET環境允許非託管的客戶端通過微軟.NET環境生成的封裝類,透明的調用.NET的程序集(Assembly)。可被調用的COM封裝類其實 是託管環境下的程序集的一個代理。他是由程序集裏面包含的元數據生成的。原數據主要是用來描述程序集的數據比如類的聲明、方法和版本信息等(類似於COM tlb文件)。所以我們可以通過封裝類像使用COM組件一樣輕鬆的調用託管環境下的程序集。

      COM
的客戶端不能直接使用.NET的程序集。當調用動作發生的時候.NET的公共語言運行時給託管對象生成一個代理類。這個代理類的主要最作用是用來在託管代碼和非託管代碼之間調度。這和COMMarshal類似。
封裝類保留了傳統COM對象的引用計數風格。當引用計數爲零時封裝類自動釋放對託管程序集的引用。當託管程序集被釋放後也會被.NET的垃圾收集器標定爲可收集對象。
       Type Library Exporter (Tlbexp.exe )
.NET環境提供的一個命令行工具這個工具可以爲.NET託管環境下的類導出類型庫(*.tlb文件)。Tlbexp.exe是根據託管環境的程序集 裏面得元數據創建的tlb文件。非託管代碼的應用程序使用這個tlb文件綁定.NET環境下的程序集。由於一個.NET的程序集可能還引用了其它的程序集 所以Tlbexp.exe可能產生一個或多個tlb文件。Tlbexp.exe文件只能生成tlb文件,但是並不爲其註冊。若想註冊請使用 regasm.exe工具,這一是一個基於命令行的工具。
       Tlbexp.exe
工具把每個具有公共屬性的類變成類型庫的coclasscoclass的名字和程序集裏類的名字保持一致。所有被顯示實現的接口都被輸出到類型庫。實現接口的類所包含的方法和屬性就不會被輸出到類型庫了。
       
當託管環境的程序集被Tlbexp.exe導出後所有的託管環境的接口和接口的方法和屬性就被轉換成COM的接口了。在缺省條件下COM組件支持雙接口,您可以使用ClassInterfaceAttribute設定接口的屬性。
舉個例子:
public interface IHello
{
void SayHello();
}
public class Imp_Hello : IHello
{
     public void ()
   {
       System.Console.WriteLine(“Hello World”);
   }
}
Tlbexp.exe
工具就會生成以下的IDL(接口定義語言)
  [uuid(xxxxxxxxxxxxxxxx),dual,odl,oleautomation]
  interface IHello :Idispatch
  {
     HRESULT SayHello();
  }
  [uuid(xxxxxxxxxxxxxxx)]
coclass Imp_Hello  ;
{
  interface Ihello; 
}
請您注意:因爲我們要導出接口和實現類,所以在上面的那段C#代碼裏面使用了public關鍵字修飾了接口和實現類。否則即使生成了tlb文件,裏面也不會包含關於接口和實現類的描述。
在您調用非託管環境下的程序集之前要先把程序集註冊到系統註冊表。.NET環境提供了一個工具叫Regasm.exe,用來完成註冊工作。
該註冊工具在註冊表裏添加了以下項目:
  
一個是.NET託管環境的類的標識符CLSID添加在HKEY_CLASSES_ROOT\CLSID

另一個在HKEY_CLASSES_ROOT\CLSID\<class I D>下,這個表項有兩個子項,
一個是ImplementedCategories通常放置類的ProgID另一個是InprocServer32用來指定.DLL的名字。
COM 客戶端企圖裝載一個託管環境程序集的類時,.NET運行環境從系統註冊表的裏面讀取程序集的數據傳送給程序集解析器。然後解析器根據名字和版本號等基本信 息定位程序集。這個程序集只有被強命名(strong name),或是被放置在應用程序的根目錄或者子目錄時才能被程序集解析器正確定位。請注意:當您沒有使用強命名時,清在註冊時加上/codebase 參數。

通過Visual Basic 6.0使用.NET程序集的過程:
1.  
Visual Basic 6.0Project菜單,點擊References
彈出References對話框
拉動滾動條找到要引用的條目點OK
創建一個.NET環境下程序集類的對象,如下:
     Dim Server As xxxxx
使用對象的方法

Visual C++6.0下使用就更爲簡單直接導入tlb文件即可如下:
#import "xxxxxx.tlb"  
請注意,在import 後面要加上named_guids屬性,否則接口的GUID將不會被定義到工程裏。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章