最近在研究產品的架構代碼,發現其中涉及到Com組件技術,即項目中的C# Project會經過Com接口來調用C++ Project中的方法,研究一下,實現一個小的例子,供本身學習。html
一. 什麼是COM Interop?java
COM Interop 是一種讓 .NET Framework 的程序可以和 COM 的程序相互操做的一種橋接技術[維基百科]。它可讓 .NET Framework 的程序使用 COM 組件,也可讓 COM 程序使用 .NET Framework 的組件。例如像咱們的產品中,它可讓C#去調用C++的方法,C++去調用C#的方法。編程
這裏涉及到一個概念,COM組件,COM技術是開發組件的一種,COM標準由微軟定義,COM組件能夠是一個動態鏈接庫(DLL), 被稱爲進程內組件(in-of-process component),也能夠是一個可執行程序(EXE),被稱爲進程外組件(out-of-process component)。COM對象是創建在二進制可執行代碼級的基礎上,而C++等語言中的對象是創建在源代碼級基礎上的,所以COM對象是語言無關的。服務器
這一特性使用不一樣編程語言開發的組件對象進行交互成爲可能。架構
這裏咱們討論其中一個簡單例子:C#調用C++代碼中的方法。app
二. 示例步驟:編程語言
簡單說明,這裏COM組件由ATL COM開發,IDE爲Visual Studio 2005,步驟以下:學習
1. 實現一個簡單的ATL COM服務器spa
A. 建立一個新的Visual C++ ATL 項目,名字:MyComServer。.net
B. 向MyComServer中添加一個新類,這裏爲了開發方便,推薦使用IDE的add->class,選擇ATL Simple Object,名字:MyTest,可看到IDE自動爲咱們生成一個COM Class CMyTest。
C. 在類視圖中,爲MyTest的接口添加方法,名字:DoSomething,其餘默認,生成後能夠根據須要添加DoSomething的方法內容。
這時IDE已經爲咱們作了不少工做,可看到CMyTest的聲明以下:
1 class ATL_NO_VTABLE CMyTest : 2 public CComObjectRootEx<CComSingleThreadModel>, 3 public CComCoClass<CMyTest, &CLSID_MyTest>, 4 public IDispatchImpl<IMyTest, &IID_IMyTest, &LIBID_MyComServerLib, /*wMajor =*/ 1, /*wMinor =*/ 0> 5 { 6 public: 7 CMyTest() 8 { 9 } 10 11 DECLARE_REGISTRY_RESOURCEID(IDR_MYTEST) 12 13 14 BEGIN_COM_MAP(CMyTest) 15 COM_INTERFACE_ENTRY(IMyTest) 16 COM_INTERFACE_ENTRY(IDispatch) 17 END_COM_MAP() 18 19 20 21 DECLARE_PROTECT_FINAL_CONSTRUCT() 22 23 HRESULT FinalConstruct() 24 { 25 return S_OK; 26 } 27 28 void FinalRelease() 29 { 30 } 31 32 public: 33 STDMETHOD(DoSomething)(void); 34 };
DoSomething方法的實現以下:
1 STDMETHODIMP CMyTest::DoSomething(void) 2 { 3 // TODO: Add your implementation code here 4 5 wprintf_s(_T("Hello, I'm here!")); 6 7 return S_OK; 8 }
2. 使用 Tlbimp 轉換 COM DLL
如今有了 COM DLL,讓咱們來看看如何從一個託管客戶端訪問它。打開 Visual Studio 命令提示,而後轉到建立 COM DLL 的目錄。如今運行如下命令:
tlbimp MSDNCOMServer.dll
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 using MyComServerLib; 5 6 namespace MyComClient 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 MyTestClass test = new MyTestClass(); 13 test.DoSomething(); 14 } 15 } 16 }
執行此C#程序,便可看到"Hello, I'm here!"的輸出信息,證實調用成功!!
三. 小結
因爲時間有限,昨天開始研究COM Interop,到今晚剛剛實現一個成功的例子,對COM技術的認識確定還有不少問題,這裏作下總結,也但願之後能繼續完善。
在兩天的時間裏,上網找到了不少很好的參考資料,以下:
1. 示例實現主要參考的文章
http://msdn.microsoft.com/zh-cn/magazine/cc163494.aspx
2. Understanding Classic COM Interoperability With .NET Applications
http://www.codeproject.com/Articles/990/Understanding-Classic-COM-Interoperability-With-NE
3. COM組件簡介
http://www.cppblog.com/3522021224/archive/2007/06/22/26803.html
4. RCW的介紹
http://www.blogjava.net/davidgw/archive/2007/07/25/132240.html
對於COM Interop技術,本身已經有了初步瞭解,有助於本身更加了解項目中的COM應用。
明天能夠進入下一個學習階段啦,開始Adapter的學習!加油!晚安:-)
Best Regards
Kevin Song