.NET 4.0: Type Equivalency (2) – 內嵌類型

來源:互聯網
上載者:User

上次我們談到了.NET 4.0中為什麼要引入Type Equivalency這樣一個新功能,這次我們來看一個比較簡單的一個程式:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Excel;
 
namespace NOPIAExcelDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Application excelApp = new Application();
            excelApp.Workbooks.Add();
            excelApp.Visible = true;
        }
    }
}

這個程式調用Excel,建立一個新的Workbook,並把Excel主程式設定為可見。

首先,我們在VS 2010中添加一個新的C#控制台項目,然後在Solution Explorer中選擇Add Reference,選擇Excel 12的Interop Assembly:

選擇點擊OK之後,在Reference下面會多出一項Microsoft.Office.Interop.Excel的引用,在其上右鍵點擊選擇Properties:

裡面有一項Embed Interop Types,修改為True。

完成之後運行程式,沒發現區別是不是?呵呵,這就對了。我們回頭來看看產生的程式碼是什麼樣子的。

用ILDASM開啟產生的EXE,雙擊Manifest,結果如下:

// Metadata version: v4.0.11001
.assembly extern mscorlib
{
   .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z/V.4..
   .ver 4:0:0:0
}
.assembly extern System.Core
{
   .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z/V.4..
   .ver 4:0:0:0
}
.assembly NOPIAExcelDemo
{
    // ...
}

上面的結果說明什麼呢?雖然我們之前通過Add Reference讓這個項目引用了Excel的PIA,但是,這個EXE並沒有對Excel的PIA的引用,也就是說,這個EXE可以獨立於PIA運行!這也正是這個Feature的最直接的作用:消除PIA,直接將Interop相關的託管類型直接嵌入(Embed)到EXE中。現在我們再看看這個EXE中又有那些類型:

非常清楚,除了NOPIAExcelDemo本身的類型之外,這個EXE把Excel的PIA中部分類型,如_Application, _Workbook, WorkBooks…等等,都包括進來了。注意這些類型都是剛才的程式所引用到的,而沒有用到是不會出現在這個EXE中的。再進一步看看Workbooks這個介面。注意我們調用到了了Workbooks.Add方法,而在這個EXE中的Workbooks類型也只有Add方法!那麼其他方法都去了那裡呢?讓我們再回頭看看PIA中的Workbooks類型是什麼樣子的:

可以看到其中的方法要多上不少。而且EXE中的Workbooks類型還有兩個奇怪的_VtblGap1_3,_VtblGap2_15。這兩個函數的作用是什麼呢?CLR的Interop有一個不太為人知的特性:因為COM中的介面是基於虛函數表的,如果只調用虛函數表中的某個函數,而不用到其他函數,那麼其他函數的進入點是可以不需要的,只需要用到的那個函數在正確的虛表位置,指向正確的函數地址即可。因此,CLR提供了一個功能,凡是介面中以_VtblGap_<N>_<M>形式命名的函數,都視為虛函數表中的M個空白項(注意N值忽略)。以Workbooks函數為例,第一個_VtblGap1_3函數表明這裡有三個不用到的虛函數表項,對應著Workbooks裡面的get_Application, get_Creator, get_Parent函數。Get_Parent之後正好是Add函數。在Add函數之後,又有一個_VtblGap2_15,對應著從Close到OpenXML這15個函數。注意.NET屬性並非函數(而是由編譯器翻譯成對應的函數),因此不算在內。這種做法可以有效節約空間佔用,減少用到的介面的複雜性。這個將Interop Assembly中的類型“拖入”到使用者的EXE中的操作,我們內部稱之為Pull-in,是由C#編譯器實現的。

談了這麼多,總結一下:C#編譯器允許將Interop Assembly中的類型直接嵌入在最終產生的EXE中,從而斷絕和Interop Assembly(包括PIA)之間的參考關聯性。需要Interop Assembly從此只限於在編譯時間,而非運行時。

不過,這個只解決了問題的一部分,那就是如何避免最終的EXE和Interop Assembly之間存在參考關聯性。然而,最重要的是,如果在另外的Assembly中,也引用到了另外版本的Interop Assembly中的某個類型,比如Office 11中的Workbooks,在這種情況下,如何解決託管類型衝突的問題呢?答案在TypeIdentifierAttribute中。如果我們查看EXE中的Workbooks的介面定義,我們會發現下面的內容:

.class interface public abstract auto ansi import Microsoft.Office.Interop.Excel.Workbooks
       implements [mscorlib]System.Collections.IEnumerable
{
  .custom instance void [mscorlib]System.Runtime.InteropServices.TypeIdentifierAttribute::.ctor(string,
                                                                                                string) = ( 01 00 00 00 00 00 ) 
  .custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = ( 01 00 24 30 30 30 32 30 38 44 42 2D 30 30 30 30   // ..$000208DB-0000
                                                                                                  2D 30 30 30 30 2D 43 30 30 30 2D 30 30 30 30 30   // -0000-C000-00000
                                                                                                  30 30 30 30 30 34 36 00 00 )                      // 0000046..
} // end of class Microsoft.Office.Interop.Excel.Workbooks

其中的TypeIdentifierAttribute是Type Equivalency,也就是NOPIA這個Feature的核心內容。在下一篇文章中,我將講解這個Attribute的作用,以及C#編譯器如何處理具有這個Attribute的類型之間的互動。



作者
: 張羿              
轉載請註明出處

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.