程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 在COM應用中使用.NET組件

在COM應用中使用.NET組件

編輯:關於.NET

首先我們來看看今天的主題和CLR Interop的關系,在我們組裡,interop這個術語包含了四個范疇,即P/Invoke, Reverse P/Invoke, COM Interop和Reverse COM Interop。前二個概念通過動態連接庫(DLL)在native世界和.NET世界中實現互通性;後兩個概念顧名思義,就是和COM打交道了。其中,COM interop是在.NET應用中使用COM組件;Reverse COM Interop指的是在COM應用中使用.NET組件。概念有些繞口令,看官先別急著拋轉,看看下圖。

可能有人會問, COM技術已經歷史悠久了,.NET程序員為什麼需要和它打交道呢?問題的答案就在於”組件”一詞。舉個例子,若干年前一個牛人寫了個程序,擴展性極佳,他用了COM把插件的接口定義的明明白白,而我們想用.NET來做這個插件。。。

為COM寫一個.NET組件,可以參照以下三部曲

1.定義.NET接口,撰寫.NET class

2.部署.NET組件

3.撰寫COM客戶端

第一步驟對經常從事.NET的開發朋友來說非常熟悉,這裡給出例子,不再贅述。

csc /target:library a.cs

第二,要部署.NET組件,這裡包括兩個方面:

regasm a.dll /tlb

1.把類型庫(type library)導出。對於COM應用來說,它只懂得類型庫,是為COM組件遵循的二進制”標准”。/tlb選項告訴regasm,導出類型庫。我們可以用oleview察看tlb的內容,如下圖所示,此前定義的.NET接口和類都在其中。

2.把步驟2中生成的dll放到注冊表中。COM並不懂得諸如GAC的概念,而是通過注冊表來查詢HKEY_CLASSES_ROOT\CLS_ID\00000000-0000-0000-FFFF-000000000004,觀察這個注冊表項,InprocServer32中把COM的動態鏈接庫指向了mscoree.dll,這就是傳說中的墊片(shim),它會負責加載公共語言運行時,並找到真正的.NET組件----a.dll。

有了以上兩步,我們就可以在COM應用中使用.NET組件了。如何撰寫COM組件超出了本文的范疇,有興趣的讀者可以參考代碼中的注釋。

cl client.cs

// client.cs
#define _WIN32_COM
#include <stdio.h>
#include <wtypes.h>
#import "a.tlb" no_namespace named_guids raw_interfaces_only
// a.tlb是第二步中導出的
int main()
{
      IUnknown *pUnk = NULL;
      IA *pIA = NULL;
      HRESULT hresult;
      // 0. 初始化COM組件
      hresult = CoInitializeEx(NULL, COINIT_MULTITHREADED);
      if (FAILED(hresult))
      {
            printf("ERROR: cannot initialze COM: 0x%x\n", hresult);
            return -1;
      }
      // 1. 獲取IUnknown接口
      hresult = CoCreateInstance(CLSID_A, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void **)&pUnk);
      if (FAILED(hresult))
      {
            printf("ERROR: cannot Get the IUnkown interface: 0x%x\n", hresult);
            return -1;
      }
      // 2. 獲得IA接口
      hresult = pUnk->QueryInterface(IID_IA, (void **)&pIA);
      if (FAILED(hresult))
      {
            printf("ERROR: cannot Convert to IDispatch interface: 0x%x\n", hresult);
            pUnk->Release();
            return -1;
      }
      pUnk->Release();
      // 3. 調用.NET組件
      hresult = pIA->Hello();
      if (FAILED(hresult))
      {
            printf("ERROR: Invoke failed: 0x%x\n", hresult);
      }
      // 4. 清理
      pIA->Release();
      CoUninitialize();
      return 0;
}

By com.microsoft.stbc.devdiv.ndp.interop.dev/mountaintai二世

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