这说来话长,编译时 Delphi 会为每个 Class 都会生成一个 MetaClass(元类) 结构,该结构
包含了指向 ClassName, Parent Class, Dynamic Methods Table 和 TypeInfo(RTTI) 的指
针和 VMT 信息,而每个对象实例的头四个字节是就一个指向该对象所属类别的 MetaClass
结构的指针. 象 if (MyForm is TForm) then ... 中, is 运算符就是通过 MyForm 所指向
的对象实例的这头四个字节是否指向 TForm 的 MetaClass 结构(当然可能需要沿 TForm 的
父类继续向上搜索) 来判断的.
那么 Exe 中,会有一套 TObject,TPersistent,TComponent,... 程序用到各个类相应
MetaClass 结构,而 DLL 同样也会有有这样一套结构,这样 DLL 加载后 , 它所包含 TObject
与 Exe 中的 TObject 是不同的,因为各自的 MetaClass 占有不同的地址空间,同样其他类也
是各有一套.因此 Exe 中的 TFont <> DLL 中的 TFont. 因此不能跨 Module 使用 is 和
as 运算符.
可以用 Runtime Package 解决这个问题, Package 是特殊的 DLL, Delphi 编译时会通过
输出函数将 Package 中定义的类的 MetaClass 结构和全局VCL对象暴露给外部,同时将
Package 中用到的其他 Module 的类和全局VCL 对象通过输入其他 Module 的输出函数来
引入.这样在程序中各 Module 就共用一套各类的 MetaClass 结构了.就不会出现上述 is,as
运算符的问题了.Delphi 自己就是使用了 Runtime Package 机制的.