程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C#中COM操作(二) 接口查詢(2)

C#中COM操作(二) 接口查詢(2)

編輯:關於C語言

第2種 與C#語言一致的類型轉換方式

大家知道在C#裡面我們要想把一種類型的引用轉成另外一種類型有兩種方式,第一種類似於(IJetEngine)engine這樣;第二種類似於engine as IJetEngine這樣.這兩種方式有的時候產生的效果是一樣的,但是嚴格說來還是有很多差別的,這個在學C#的時候大家都遇到了,這裡我也不在多說,只是提幾個下面會用到的相同點和區別.

對於都是引用類型的轉換,大家都不產生新的對象,如果轉換成功的話都是返回指向給定對象的新的類型的引用.第一種強制類型轉換(暫且稱作這樣吧),在遇到轉換不成功的時候會拋出異常,但是大多數時候我們都不希望拋出異常,而是希望當轉換不成功的時候,返回null引用就可以了,而這正是第二種方式'as'方式所能夠達到的.

這兩種類型轉換方式同樣可以作用在COM對象的C#包裝的引用上,而產生的效果與前面用QueryInterface產生的效果是一樣的,都是返回一個給定的接口,只不過這裡以具體的接口聲明的引用代替了之前的接口指針.而且這種轉換方式與一個普通的C#托管類轉換到實現的接口的方式簡直是一模一樣.代碼風格的一致性也得到了更好的體現.

需要注意的是我們用這種方式用COM對象的類型轉換(其實是接口查詢)的時候,還是與普通的拖管類的類型轉換有一些細微的差別,但不是體現在代碼上,而是體現在轉換前後的兩個類型的關系上:

1 public interface IDemo
2 {
3 }
4 public class Demo : IDemo
5 {
6 }
7
8 public class Demo1
9 {
10 }
11
12 object o1 = new Demo();
13 object o2 = new Demo();
14 IDemo d1 = o1 as IDemo; // d1獲得了一個IDemo的引用
15 IDemo d2 = o2 as IDemo; // d2 值為 null
16
17 IJetEngine e = new JetEngineClass() as IJetEngine; // e獲得了一個IJetEngine的引用

從這裡我們可以看到普通托管類如果聲明的時候沒有實現某個接口,那麼在類型轉換的時候,一定不會轉成功,但是一旦某個托管類聲明成了COM類的包裝類以後,不管在聲明的時候有沒有實現相應的接口,只要所指代的COM類用QueryInterface能夠找到這個接口,甚至是一個聚合的接口,那麼這裡的轉換一定成功.在這裡類型轉換的功能就好像就成了QueryInterface的功能了. 同樣的C#裡面與as操作符是孿生兄弟的"is"操作符在這裡也不在是面向對象裡面的"is a...", "has a ..."的定義,變成了QueryInterface能不能成功的標志了.

第3種 聲明的接口從IUnknown接口派生,或包含IUnknown接口的三個方法,我們還是來看看具體的代碼:

1
2
3[ComImport, Guid("00000000-0000-0000-C000-000000000046")]
4public interface IUnknown
5{
6  void QueryInterface([In] ref Guid iid, [Out] out IntPtr ppvObj);
7  int AddRef();
8  int Release();
9}
10
11[ComImport, CoClass(typeof(JetEngineClass)), Guid("9F63D980-FF25-11D1-BB6F-00C04FAE22DA")]
12public interface IJetEngine1 : IUnknown
13{
14  void CompactDatabase(
15    [In, MarshalAs(UnmanagedType.BStr)] string SourceConnection,
16    [In, MarshalAs(UnmanagedType.BStr)] string Destconnection
17    );
18  void RefreshCache([In, MarshalAs(UnmanagedType.Interface)] object Connection);
19}
20
21[ComImport, CoClass(typeof(JetEngineClass)), Guid("9F63D980-FF25-11D1-BB6F-00C04FAE22DA")]
22public interface IJetEngine2
23{
24  void QueryInterface([In] ref Guid iid, [Out] out IntPtr ppvObj);
25  int AddRef();
26  int Release();
27  
28  void CompactDatabase(
29    [In, MarshalAs(UnmanagedType.BStr)] string SourceConnection,
30    [In, MarshalAs(UnmanagedType.BStr)] string Destconnection
31    );
32  void RefreshCache([In, MarshalAs(UnmanagedType.Interface)] object Connection);
33}
34
35IJetEngine1 iJetEngine = GetJetEngine() as IJetEngine1;
36IntPtr p1;
37iJetEngine.QueryInterface(typeof(IUnknown).Guid, out p1);
38
39IJetEngine2 iJetEngine = GetJetEngine() as IJetEngine2;
40IntPtr p2;
41iJetEngine.QueryInterface(typeof(IUnknown).Guid, out p2);

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