探讨生成类型库
让我们迅速地看一下由程序集注册工具 (REGASM)生成的被放到类型库中的信息。通过OLEVIEW的类型库查看器打开类型库,因此你可以研究IDL文件,IDL文件是从类型库反向运行的。
Collapse如果看一下coclass这一章,它指定默认接口来担任被带有_ (underscore)特点前缀的类型名称的工作。这个接口被称为类型接口,它的方法由类型的许多非静态公共方法,领域和属性组成。因为你用ClassInterface 属性标记了你的.NET类型,所以生成了类型金额类型接口。这个属性告诉类型库生成工具(例如:RegAsm.exe和TlbExp.exe)如何生成默认接口(也就是我们所知道的类型接口),如何把类型的所有公共方法,领域和属性增加到其中,因此它能被展示给COM 感知客户端。
[
uuid(A9F20157-FDFE-36D6-90C3-BFCD3C8C8442),
version(1.0)
]
library Temperature
{
importlib("mscorlib.tlb");
importlib("STDOLE2.TLB");
interface _TemperatureComponent;
typedef [uuid(0820402E-B8B6-330F-8D56-FF079E5B4659), version(1.0),
custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "WeatherIndications")]
enum {
WeatherIndications_Sunny = 0,
WeatherIndications_Cloudy = 1,
WeatherIndications_Rainy = 2,
WeatherIndications_Snowy = 3
} WeatherIndications;
[
uuid(01FAD74C-3DC4-3DE0-86A9-8490FAEE8964),
version(1.0),
custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9},
"TemperatureComponent")
]
coclass TemperatureComponent {
[default] interface _TemperatureComponent;
interface _ Object;
};
[
odl,
uuid(C51D54FA-7C81-35A5-9998-3963EAB4AA12),
hidden,
dual,
nonextensible,
oleautomation,
custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9},
"TemperatureComponent")
]
interface _TemperatureComponent : IDispatch {
[id(00000000), propget]
HRESULT ToString([out, retval] BSTR* pRetVal);
[id(0x60020001)]
HRESULT Equals([in] VARIANT obj,
[out, retval] VARIANT_BOOL* pRetVal);
[id(0x60020002)]
HRESULT GetHashCode([out, retval] long* pRetVal);
[id(0x60020003)]
HRESULT GetType([out, retval] _Type** pRetVal);
[id(0x60020004), propget]
HRESULT Temperature([out, retval] single* pRetVal);
[id(0x60020004), propput]
HRESULT Temperature([in] single pRetVal);
[id(0x60020006)]
HRESULT DisplayCurrentTemperature();
[id(0x60020007)]
HRESULT GetWeatherIndications([out, retval]
WeatherIndications* pRetVal);
};
};
如果没有把ClassInterface属性连接到.NET组件类型,仍然会生成一个默认类型接口。但是在这种情况下,它是一个基于IDispatch 的类型接口,此默认类型接口没有包含被展示的任何方法的类型信息,也没有包含它们的DISPIDs。只有晚期绑定用户可以使用这种类型接口类型。效果与将ClassInterfaceType.AutoDispatch值应用到ClassInterface属性的效果一样。AutoDispatch选择的优点就是:因为DISPIDs没有而被高速缓存,也没有作为可以利用的类型信息的一部分,当发行一个组件的新版本时,它们没必要打破现有的客户端,因为通过使用像IDispatch::GetIDsOfNames.一样的事物,客户端在运行时获得了DISPIDs。