天天看點

C#建立VC可調用的COM元件

簡述

本文詳細闡述如何用C#建立一個COM元件,并能用VC6.0等調用。并附有完整測試通過的代碼。該功能總體看來很簡單。可是我在第一次用C#做COM的時候,痛不欲生。因為很少有人寫這類文章。而且就算有代碼也是亂帖。根本是讓人誤入歧途。後來在C# help上面看一個老外寫的文章Building COM Objects in C#(上面有一個完整的SQL SERVER執行個體),才完成該功能。拿來分享。

開發工具:VS2008

          VS2008指令提示符(呵呵,這個你應該可以找到在什麼地方吧)

附:本文适用任何VS系列工具。

在用C#建立COM時,一定要記住以下幾點:

1:所要導出的類必須為公有;

2:所有屬性、方法也必須為公有;

  3:要導出的屬性、方法必須用接口方式;如果沒有在接口中聲明,即使該方法(屬性)為公有,也不能正常導出到COM。但他們可以被别的.NET程式所使用;

  4:所有的事件也必須用接口方式;

現在我們開始正題:

一、建立一個Visual C#工程(習慣這種叫法了,現在應該叫解決方案)。

選擇類型“類庫”;我就叫MyCom吧。

二、編寫導出接口。

為了大家了解友善,我僅一加法操作舉例。如下:

  1. [Guid("154BD6A6-5AB8-4d7d-A343-0A68AB79470B")]
  2.     public interface MyCom_Interface
  3.     {
  4.         [DispId(1)]
  5.         int Add(int a, int b);
  6.   }

複制代碼 Guid為全局唯一辨別,可以用VS2008的指令提示符中輸入:guidgen 就會出來它的視窗。在幾個複選框選擇最後一個Registry Format,點選New Guid,然後COPY就行了(以下如有guid的字元串,全部同樣操作)

  [DispId(1)]為函數的辨別。如果有多個函數可相應的在函數前面加[DispId(2)], [DispId(3)]…

三、建立事件接口。

  1.     [Guid("D11FEA37-AC57-4d39-9522-E49C4F9826BB"),
  2.     InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
  3.     public interface MyCom_Events
  4.     {
  5.     }

複制代碼 Guid同二,不多說

InterfaceType表求向COM公開的方式,這裡選擇為以排程的方式向COM公開。

四、建立具體類:

  1. [Guid("2E3C7BAD-1051-4622-9C4C-215182C6BF58"),
  2.       ClassInterface(ClassInterfaceType.None),
  3.       ComSourceInterfaces(typeof(MyCom_Events))]
  4.     public class Class1 : MyCom_Interface
  5.     {
  6.         public int Add(int a, int b)
  7.         {
  8.             return a + b;
  9.         }
  10. }

複制代碼 至此,代碼完畢。很簡單吧。别急,後面來有常常被忽略的步驟,先把整體代碼放在下面(注意引用InteropServices):

  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Text;
  4. namespace MyCom
  5. {
  6.     [Guid("154BD6A6-5AB8-4d7d-A343-0A68AB79470B")]
  7.     public interface MyCom_Interface
  8.     {
  9.         [DispId(1)]
  10.         int Add(int a, int b);
  11.     }
  12.     [Guid("D11FEA37-AC57-4d39-9522-E49C4F9826BB"),
  13.     InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
  14.     public interface MyCom_Events
  15.     {
  16.     }
  17.     [Guid("2E3C7BAD-1051-4622-9C4C-215182C6BF58"),
  18.       ClassInterface(ClassInterfaceType.None),
  19.       ComSourceInterfaces(typeof(MyCom_Events))]
  20.     public class Class1 : MyCom_Interface
  21.     {
  22.         public int Add(int a, int b)
  23.         {
  24.             return a + b;
  25.         }
  26.     }
  27. }

複制代碼 五、大家都知道COM是需要注冊的。

注冊時要加密鑰檔案.SNK。這一部就是生成SNK檔案。進入VS2008指令提示符。用指令:sn –k MyCom.snk回車。我的在E:\vs2008\vc下面就生成了一個(MyCom.snk)的檔案。(你們可以根據自己的指令提示符所在的檔案目錄下去找)。然後把它COPY到你的工程根目錄下。

六、打開AssemblyInfo.cs。

在裡面加入[assembly:AssemblyKeyFile("MyCom.snk")]

七、(1)項目屬性->應用程式->程式集資訊->選中“使程式集COM可見”。(2)項目屬性->生成->選中“為COM互操作注冊”。

八、生成。如果在Debug下有一個MyCom.tlb,那你就成功了(肯定還有MyCom.dll)要此tlb檔案是為了在VC6.0裡面測試。

九、在VC裡面建一個MFC對話框程式(當然Console程式也一樣,我為了看着友善)。建好後,把剛剛生成的MyCom.tlb拷到你的根目錄下。

十、選在代碼裡加入#import "MyCom.tlb",然後編寫核心測試代碼:(我是在一個Button1按鈕裡面添加的),如下:

  1. void CTestDlg::OnButton1() 
  2. {
  3.     CoInitialize(NULL);  //注意初始化
  4.     MyCom::MyCom_InterfacePtr p(__uuidof(MyCom::Class1));  //建立智能指針
  5.     MyCom::MyCom_Interface *s = p;
  6.     int a = 3;
  7.     int b = 6;
  8.     int c = s->Add(a,b);
  9.     CString str;
  10.     str.Format("%d",c);
  11.     MessageBox(str);
  12. }

複制代碼 當彈出一個9,就說明你已經成功了。

繼續閱讀