用C#創(chuàng)建COM組件全過(guò)程
本文詳細(xì)闡述如何用C#創(chuàng)建COM組件,并能用VC6.0等調(diào)用。并附有完整測(cè)試通過(guò)的代碼。該功能總體看來(lái)很簡(jiǎn)單??墒俏以诘谝淮斡肅#做COM的時(shí)候,痛不欲生。因?yàn)楹苌儆腥藢戇@類文章。而且就算有代碼也是亂帖。根本是讓人誤入歧途。后來(lái)在C# help上面看一個(gè)老外寫的文章 (上面有一個(gè)完整的SQL SERVER實(shí)例),才完成該功能。拿來(lái)分享。
開(kāi)發(fā)工具:VS2008
VS2008命令提示符(呵呵,這個(gè)你應(yīng)該可以找到在什么地方吧)
附:本文適用任何VS系列工具。
在用C#創(chuàng)建COM組件時(shí),一定要記住以下幾點(diǎn):
1:所要導(dǎo)出的類必須為公有;
2:所有屬性、方法也必須為公有;
3:要導(dǎo)出的屬性、方法必須用接口方式;如果沒(méi)有在接口中聲明,即使該方法(屬性)為公有,也不能正常導(dǎo)出到COM。但他們可以被別的.NET程序所使用;
4:所有的事件也必須用接口方式;
現(xiàn)在我們開(kāi)始正題:
一、新建一個(gè)Visual C#工程(習(xí)慣這種叫法了,現(xiàn)在應(yīng)該叫解決方案),選擇類型“類庫(kù)”;我就叫MyCom吧。
二、編寫導(dǎo)出接口。為了大家理解方便,我僅一加法操作舉例。如下:
- [Guid("154BD6A6-5AB8-4d7d-A343-0A68AB79470B")]
- public interface MyCom_Interface
- {
- [DispId(1)]
- int Add(int a, int b);
- }
Guid為全局唯一標(biāo)識(shí),可以用VS2008的命令提示符中輸入:guidgen 就會(huì)出來(lái)它的窗口。在幾個(gè)復(fù)選框選擇最后一個(gè)Registry Format,點(diǎn)擊New Guid,然后COPY就行了(以下如有g(shù)uid的字符串,全部同樣操作)
[DispId(1)]為函數(shù)的標(biāo)識(shí)。如果有多個(gè)函數(shù)可相應(yīng)的在函數(shù)前面加[DispId(2)], [DispId(3)]…
三、創(chuàng)建事件接口。
- [Guid("D11FEA37-AC57-4d39-9522-E49C4F9826BB"),
- InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
- public interface MyCom_Events
- {
- }
Guid同二,不多說(shuō)
InterfaceType表求向COM公開(kāi)的方式,這里選擇為以調(diào)度的方式向COM公開(kāi)。
四、 創(chuàng)建具體類:
- [Guid("2E3C7BAD-1051-4622-9C4C-215182C6BF58"),
- ClassInterface(ClassInterfaceType.None),
- ComSourceInterfaces(typeof(MyCom_Events))]
- public class Class1 : MyCom_Interface
- {
- public int Add(int a, int b)
- {
- return a + b;
- }
- }
至此,代碼完畢。很簡(jiǎn)單吧。別急,后面來(lái)有常常被忽略的步驟,先把整體代碼放在下面(注意引用InteropServices):
- using System;
- using System.Runtime.InteropServices;
- using System.Text;
- namespace MyCom
- {
- [Guid("154BD6A6-5AB8-4d7d-A343-0A68AB79470B")]
- public interface MyCom_Interface
- {
- [DispId(1)]
- int Add(int a, int b);
- }
- [Guid("D11FEA37-AC57-4d39-9522-E49C4F9826BB"),
- InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
- public interface MyCom_Events
- {
- }
- [Guid("2E3C7BAD-1051-4622-9C4C-215182C6BF58"),
- ClassInterface(ClassInterfaceType.None),
- ComSourceInterfaces(typeof(MyCom_Events))]
- public class Class1 : MyCom_Interface
- {
- public int Add(int a, int b)
- {
- return a + b;
- }
- }
- }
五、大家都知道COM是需要注冊(cè)的。注冊(cè)時(shí)要加密鑰文件.SNK。這一部就是生成SNK文件。進(jìn)入VS2008命令提示符。用命令:sn –k MyCom.snk回車。我的在E:\vs2008\vc下面就生成了一個(gè)(MyCom.snk)的文件。(你們可以根據(jù)自己的命令提示符所在的文件目錄下去找)。然后把它COPY到你的工程根目錄下。
六、打開(kāi)AssemblyInfo.cs。在里面加入[assembly:AssemblyKeyFile("MyCom.snk")]
七、(1)項(xiàng)目屬性->應(yīng)用程序->程序集信息->選中“使程序集COM可見(jiàn)”。(2)項(xiàng)目屬性->生成->選中“為COM互操作注冊(cè)”。
八、生成。如果在Debug下有一個(gè)MyCom.tlb,那你就成功了(肯定還有MyCom.dll)要此tlb文件是為了在VC6.0里面測(cè)試。
九、在VC里面建一個(gè)MFC對(duì)話框程序(當(dāng)然Console程序也一樣,我為了看著方便)。建好后,把剛剛生成的MyCom.tlb拷到你的根目錄下。
十、選在代碼里加入#import "MyCom.tlb",然后編寫核心測(cè)試代碼:(我是在一個(gè)Button1按鈕里面添加的),如下:
- void CTestDlg::OnButton1()
- {
- CoInitialize(NULL); //注意初始化
- MyCom::MyCom_InterfacePtr p(__uuidof(MyCom::Class1)); //創(chuàng)建智能指針
- MyCom::MyCom_Interface *s = p;
- int a = 3;
- int b = 6;
- int c = s->Add(a,b);
- CString str;
- str.Format("%d",c);
- MessageBox(str);
- }
當(dāng)彈出一個(gè)9,就說(shuō)明你已經(jīng)成功用C#創(chuàng)建COM組件了。
【編輯推薦】