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

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

編輯:關於C語言

上面兩種方式都是正確的,需要注意的是如果把IUnknown的方法放到IJetEngine2接口內部聲明的話,必須放到函數聲明的最開始位置,想想虛函數編譯後函數指針的順序就明白了.不過這種方式有個不太好的地方就是搞了老半天好不容易才得到的一個對COM對象的包裝類,經過這麼一查詢接口,又回到了指針形態,很是不爽.

這裡說了幾種COM接口查詢的方式,無非就是COM對象的.Net包裝類的引用或者IntPtr指針轉來轉去的,這兩種COM對象的引用到底哪種更好點呢.我的建議是能用包裝類引用的盡量用包裝類引用吧,實在不濟的時候沒有聲明包裝類也可以用object作為引用類型.

我是不太喜歡直接操作COM對象的IntPtr指針的(非它類型的IntPtr指針除外,例如一個指向內存數據塊的指針),除非是實在沒有辦法的時候.原因嘛,就是因為COM引用計數器的問題.前面我們也提到過了,使用COM包裝類的引用的時候,不管在接口之間怎麼轉換,都不會產生新的對象;還有一點就是COM對象的引用計數只會在生成包裝類的實例的時候才會增加1;另外COM包裝類也是一個托管類,只不過是一個比較特殊的托管類而以,所以它的實例的生命周期還是遵循了一般托管類的生命周期的定義----當該對象沒有被任何一個變量所引用的時候,這個對象就需要被垃圾回收了.結合以上幾條,一個COM對象只被包裝類的實例引用時,在整個包裝類的生命周期內,COM的引用計數都只是1,直到包裝類被垃圾回收了,這個時候CLR會自動減少這個包裝類所指向的COM對象的引用計數,當計數器為0時COM對象也就被銷毀了.這個比C++裡面的ComPtr還要妙,ComPtr在每賦值一次的時候還要對引用計數加1呢.

回過頭來我們再看看使用IntPtr的情況,正如前面所說的,理論上來講每賦值一次IntPtr都需要對COM計數加1,每當一個有效的IntPtr不再使用了又要對其所引用的COM對象的計數器減1,對於現在C#程序員來說,很多甚至對內存的動態分配和釋放都沒有概念,更是會經常還要忘了COM計數器的這些操作,編程的樂趣就這樣被消磨得沒有了,何其痛苦呀.

另外就是在使用自己定義COM包裝類和接口的時候,經常會遇到一個接口的方法裡面用到了另外的接口,如果一層一層展開下去會需要聲明一大堆的接口定義,而我們其實中是需要其中的一個很少的功能,這樣太得不嘗失了.最簡單的方法就從我們的需要出發,保留我們需要調用的方法的接口的聲明,其它不相干的接口的參數用object類型或IntPtr定義,在用object作為參數類型的時候需要在參數上加上MarshalAs(UnmanagedType.Interface)特性,以表明這是一個COM接口,而不是一個其它什麼類型,例如結構什麼的.

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