走近COM Interop——RCW入門
走近COM Interop
—— RCW入門
緒言
由於目前加入了一個負責將原有系統移植至.Net平臺的專案組,花了些時間對COM-->.Net進行了些基礎研究。貼出此文,希望與各位分享。不足之處,請各位指正。先謝啦。
一、基礎概念
什麼是COM Interop?COM Interop看上去象是介乎於COM和.Net之間的一條紐帶,一座橋樑。為了保持向後相容,COM Interop可以使得.Net程式在不修改原有COM元件的前提下方便的訪問COM元件。這一點是非常重要的。事實上,全球的COM元件的程式碼量估計可能有數十億行,擁有這些COM元件的公司不可能重寫這些元件,所以COM Interop的存在為有此需求的開發者提供了很好的解決方案。
大家都知道,COM和.NET之間存在著非常大的差異,為了使兩者可以有機的結合在一起進行協同工作,COM Interop中實際存在著2種橋接方式。一種是RCW,Runtime Callable Wrapper(水平有限,不知道精確的翻譯是什麼,這兒就不予詳解了。);另一種是CCW,COM Callable Wrapper。後者,將在後續的相關文章中進行討論,這兒就不再贅述了,本文主要關注的是前者。RCW是在執行時通過CLR從Interop裝配件(Interop Assembly)的後設資料中獲取相關資訊動態的例項化而得到的。個人認為,可以把它理解為是介乎於COM和.Net應用程式之間的一個代理,.Net應用程式對COM元件的每個呼叫請求都是通過這個RCW中轉的。使用者將感覺不到自己是在呼叫COM元件,一切都是這麼的自然,和呼叫一個.Net元件沒有任何區別。使用C++的朋友都知道,在C++中如果想要例項化一個COM物件,需要使用CoCreateInstance。而當我們有了RCW之後,一切都變得簡單,我們可以在C#中使用new來直接例項化這個COM物件。
需要注意的是,一個COM元件(指的是一個例項,即一個DLL檔案)由且僅由一個RCW負責維護。那麼這兒有一個問題了,對於一個COM元件的不同版本,是不是就會有不同的RCW與之相對應呢?答案是肯定的。那有些朋友會說,.Net中的元件不是已經解決了COM中的“DLL HELL”問題了嗎?按上面的說法,似乎並沒有得到解決嘛?這兒我要說的是,在.Net中匯入一個COM元件的不同版本,是會出現此類問題。解決此類問題的方法是使用PIA(Primary Interop Assembly),這部分不在本文的討論範圍之內,我將在後續的相關文章中和大家進行討論。
二、實戰演練
.Net提供三種途徑供我們匯入一個COM元件:
- 通過Visual Studio .Net提從的“新增引用”功能
- 通過命令列方式——TLBIMP.EXE
- 使用System.Runtime.InteropServices.TypeLibConverter類程式設計實現匯入功能
第一種方式無須贅述,非常的簡單。第三種方式我會說明PIA的用法的同時,對此方法的使用加以說明。不過,我的水平不高,各位不要要求太高嘍。^_^ 言歸正傳,本文關注的是第二種方式。我們可以直接使用此工具提供的最簡單的呼叫方式:TLBIMP TestObj.dll。但需要提醒各位的是,如果我們使用這種方式匯入一個COM元件的話,我們將“犧牲”原有的COM元件,這樣做是很危險的。個人認為,最簡單的呼叫方式是TLBIMP TestObj.dll /out:interop.TestObjLib.dll。這樣,執行後將會產生一個名為interop.TestObjLib.dll的COM Interop。下面將給出簡單的例子以說明整個過程。
1、首先用VB寫的一個簡單的ActiveX Dll
'Project name is TestObjList, class name is TestObj
Option Explicit
Public Function Add(ByVal iValue As Integer) As Integer
Add = iValue + 1
End Function
2、使用命令列工具匯入這個COM元件
TLBIMP TestObjLib.dll /out:interop.TestObjLib.dll
3、在一個.Net Windows Forms中寫一段呼叫此元件的測試程式碼
using interop.TestObjLib;
private void button1_Click(object sender, System.EventArgs e)
{
TestObjClass obj = new TestObjClass();
int num = 1;
MessageBox.Show(obj.Add(num).ToString());
}
此處需要說明一點,當TLBIMP.EXE在生成Interop裝配件時會在原COM中的類的名字後面加上一個"Class"。呼叫時,請各位注意。
相關文章
- COM Interop入門
- 前端演算法入門 - 走近紅黑樹前端演算法
- 在 .NET Compact Framework 2.0 中使用 COM InteropFramework
- Composer 快速入門
- COM入門(轉載)
- SalesForce.com 入門教程Salesforce
- Docker Compose 快速入門Docker
- 在c#如何:使用 COM Interop 建立 Excel 電子表格C#Excel
- 如何獲得COM的Interop互動庫C#原始碼C#原始碼
- PIA (Primary Interop Assembly) & AIA (Alternate Interop Assembly)簡介AI
- 精讀《Function Component 入門》Function
- Prometheus入門 | Opensource.comPrometheus
- Apache Commons IO入門教程Apache
- PHP 之 Composer 新手入門指南PHP
- Azure Command Line (一)入門
- Web Components 入門例項教程Web
- OpenAI Chat completion API 入門指南OpenAIAPI
- java之使用CompletableFuture入門2Java
- FreeBSD Command Tools入門必看(轉)
- Docker從入門到精通(八)——Docker ComposeDocker
- SAP Commerce Cloud 專案 Spartacus 入門Cloud
- 華為開源專案ServiceComb快速入門
- csharp excel interop programmingCSharpExcel
- Jetpack Compose學習(1)——從登入頁開始入門Jetpack
- webpack -> vue Component 從入門到放棄(四)WebVue
- 推薦系統入門(Top-N recommendation)
- vue入門筆記體系(四)computed和watchVue筆記
- Docker基礎、Machine、Compose、Swarm入門與實踐DockerMacSwarm
- Composer - 快速入門(如有遺漏,敬請諒解)
- Android Compose 入門,深入底層原始碼分析Android原始碼
- 走近中國的Oracle (轉)Oracle
- Microsoft.Office.Interop.Word.Application wordApplication = new Microsoft.Office.Interop.Word.Application()報錯ROSAPP
- 入門入門入門 MySQL命名行MySql
- docker和docker compose安裝使用、入門進階案例Docker
- Svelte入門——Web Components實現跨框架元件複用Web框架元件
- Common Lisp入門筆記(一)7個基本運算子Lisp筆記
- comScore:功能手機扮演入門級手機的角色
- vue2.x版本中computed和watch的使用入門詳解-computed篇Vue