`
lovnet
  • 浏览: 6820127 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

.NET 4.0: Type Equivalency (2) - 内嵌类型

阅读更多

上次我们谈到了.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:

image

选择点击OK之后,在Reference下面会多出一项Microsoft.Office.Interop.Excel的引用,在其上右键点击选择Properties:

image

里面有一项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中又有那些类型:

image

非常清楚,除了NOPIAExcelDemo本身的类型之外,这个EXE把Excel的PIA中部分类型,如_Application, _Workbook, WorkBooks…等等,都包括进来了。注意这些类型都是刚才的程序所引用到的,而没有用到是不会出现在这个EXE中的。再进一步看看Workbooks这个接口。注意我们调用到了了Workbooks.Add方法,而在这个EXE中的Workbooks类型也只有Add方法!那么其他方法都去了那里呢?让我们再回头看看PIA中的Workbooks类型是什么样子的:

image

可以看到其中的方法要多上不少。而且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的类型之间的交互。


作者
: 张羿
转载请注明出处

分享到:
评论

相关推荐

    People 25 Years and Over Highest Education Level 25岁及以上文化程度的人-数据集

    这是由美国联邦调查局经济数据库(FRED)托管的美国人口普查局的数据集。...people-25-years-and-over-who-have-completed-high-school-includes-equivalency-for-the-united-states-discontinued_metadata.json

    pythonHSE

    Python HSE,全称为High School Equivalency,与Python编程语言相结合,可能指的是在高中教育水平上使用Python进行计算机科学教育或考试。Python是一种高级、解释型、交互式和面向对象的脚本语言,因其简洁易读的...

    Java_面向对象设计原则总结

    2 里氏替换原则-Liskov Substitution Principle (LSP) 3 接口分隔原则-Interface Segregation Principle (ISP) 4 单一职责原则-Single Responsibility Principle (SRP) 5 开闭原则-The Open-Closed ...

    Equivalency_Between_Strapdown_Inertial_Navigation__inertial_stra

    捷联惯性导航算法实用中有关圆锥运动和划船运动等价性的处理

    java设计原则16种:总结完整版(PDF)

    ##### 2. 里氏替换原则(Liskov Substitution Principle, LSP) **定义**:里氏替换原则指出,所有引用基类的地方必须能透明地使用其子类的对象。这意味着只要父类能够出现的地方,子类就一定可以出现。 **原理**...

    NIST SP800-29.pdf

    NIST developed the standard and an associated metric (the Derived Test Requirements for FIPS 140-1) to ensure repeatability of tests and equivalency in results across the testing laboratories....

    AN5017_坐标系1

    2. 术语(Terminology) 文档中可能涉及的关键术语包括: - Aerospace坐标系(Aerospace Coordinate System):也称为NED(North, East, Down)坐标系,其中x轴指向北,y轴指向东,z轴向下。 - Android坐标系...

    html5网页设计作业.zip

    其次,HTML5增强了表单控制,新增了多种输入类型,如色选器(&lt;input type="color"&gt;)、日期选择器(&lt;input type="date"&gt;)、电子邮件输入(&lt;input type="email"&gt;)等,这使得用户界面更加友好,同时减少了客户端验证的工作...

    VASS_Automation Standard_en.ppt

    Cost savings from software design in plant operation and maintenance due cross-supplier functional equivalency Technical advantages in the application program Shorter commissioning times ...

    C语言项目式编程.zip

    2. **函数使用**:通过函数来组织代码,实现模块化编程,理解函数的定义、调用、参数传递等概念。 3. **指针操作**:C语言的精髓之一在于指针,通过项目可以深入理解指针的使用,包括指针变量、指针运算、动态内存...

    test_csa.rar_made

    This code was taken from csa.irde.to. It was made optimized and usable for out project. We created the user interface ... We have also incorporated a functionality that check two files for equivalency.

    test_csa.zip_made

    We have also incorporated a functionality that check two files for equivalency. This does the quivalency check in a way that would ensure that the same data data is always recoginzed as the same.

    基于复合等效可信度加权的Bayes融合评估方法

    To improve this situation, the physical equivalency credibility is defined by analyzing different test surroundings. Moreover, the composite equivalency weight of prior sample is decided by f

    基于多相滤波器器组的数字通信接发机原理.pdf

    文章还提到了一个关键点,那就是等效性定理(equivalency theorem)。这个定理在多相滤波器组的设计和分析中起着重要作用,因为它允许设计者和工程师在模拟和数字域之间进行转换,简化了设计过程。 最后,文中还...

    先来先服务FCFS和短作业优先SJF进程调度算法 银行家算法 虚拟内存页面置换算法 磁盘调度算法

    在操作系统中,进程调度是管理CPU执行权分配的关键部分,它确保系统资源高效地被多个并发运行的进程共享。本文将深入探讨四种重要的调度算法:先来先服务(FCFS)、短作业优先(SJF)、银行家算法以及虚拟内存中的页面...

    html综合练习.zip

    HTML(HyperText Markup Language)是用于创建网页的标准标记语言,它是Web开发的基础,允许开发者通过文本、图像、链接等元素构建交互式的网页。... ...接着是`&lt;head&gt;`部分,这里放置元数据,如字符编码(`...

Global site tag (gtag.js) - Google Analytics