只要开始在已有部件的新版本上工作,就需要指定一个类型库,Visual Basic 用它作为兼容性的参考点。多数情况下,这个类型库就包含在最后发布的部件版本的可执行文件(.Exe、.dll,或 .ocx 文件)中。
对于更新的部件,每次为它建立中间版本时, Visual Basic 将从该 .Exe 文件中提取有关旧接口的信息,并把它和类模块的新接口相比较。
“为兼容性提供参考点”介绍了建立参考点的过程。
重点 保持被指定为引用版本的 .Exe 文件备份和新版本的编译备份之间的独立。
每次进行中间编译时,Visual Basic 都会向可执行文件中添加新的接口标识符集,每个类模块一个标识符。如果把编译备份指定为参考版本,那么每次版本兼容的中间编译所增加的接口标识符都会堆积在一起。(对于版本相同的编译,接口标识符不会改变。)
除了每个接口标识符要占用十六个字节以外,在有些情况下,在可执行文件中包含无用的接口标识符— 只有测试应用程序曾经使用过的中间版本— 将会减慢进程间对部件的访问,同时安装该部件的计算机的 Windows 注册表也会被无用的接口标识符弄得凌乱不堪。
如果参考版本是上一次发布的可执行文件的备份,那么所有的中间编译会有相同的接口版本号,而最终编译只包含所需的接口标识符:所有参考版本的标识符集(为了提供向后兼容)再加上新版本中所有类的接口标识符集。
注意 开发部件的第一个版本时,使用“工程兼容”而不是“二进制兼容”,情况恰好相反,参考版本会成为中间编译的版本。这不会使类型库膨胀,因为“工程兼容”从不保存接口标识符。
Visual Basic 为新类型库生成版本号,是通过在参考版本中找到类型库的版本号后递增,因此部件的发布版本形成了一个链,每一环都是从它前面一环得到的。如上所述,每个新版本都包含了所有以前版本的接口标识符,因此用以前的任何版本编译的客户应用程序都可以在最新的版本下继续运行。
在部件的版本出现分支时就会产生版本树— 也就是说,基于相同的源代码生成了两个存在实际差别的部件时就会产生版本树。保持部件的版本直线发展,避免分支是很重要的。
图 7.4 显示了版本树可能引起的一些问题。(版本号只作说明用,并不代表实际的类型库版本号。)
图 7.4 版本树的问题
右边的长分支表示某个部件可执行文件的四个连续版本,以及一个新的可执行文件,它是通过向类型库版本为 1.3 的可执行文件增加源代码而创建的。
最新的可执行文件应该在编译时使用版本 1.3 作为它的参考版本。新的类型库版本号应该是 1.4。这样,.Exe 文件就可以与使用以前版本的客户应用程序保持兼容。
由于处在兼容版本链的末端,新的可执行文件还可以用版本 1.0 作为参考版本进行编译。在这种情况下,它的类型库版本号是 1.1。客户应用程序要利用新版本的优点会出现问题。如果新版本被放在某台有早期版本 1.1 的可执行文件的计算机上,那么新的特性不可用,而且应用程序会出现故障。
如果计算机上安装了使用版本号为 1.1、1.2 或 1.3 的类型库编译的客户应用程序,再安装新的部件会产生另外的问题。应该递增每个新的可执行文件的文件版本号,这样就可以保证安装程序能够替换可执行文件的早期版本。(请记住,文件版本号是独立于类型库的版本号的。)
这样,包含版本 1.0 和 1.1 类型库的接口标识符的新的可执行文件,将替代包含版本 1.0 到 1.3 的类型库的接口标识符的旧可执行文件。
如果计算机上已包含使用版本 1.2 和 1.3 的类型库编译的客户应用程序,那么这些客户应用程序将无法使用部件的新版本。
树的左边表示分叉的版本。如果部件早期版本的源代码被用来作为某个新部件的基础,而添加的类又不在主要的版本中,此时会出现分叉的情况,
如果部件的可执行文件被用来作为分叉版本的参考版本,那么分叉版本及其后继的类型库版本号就会和部件的版本号重叠。这种结果对于客户应用程序来说是灾难性的。
提示 如上所述,只要把部件可执行文件(.Exe、.dll,或 .ocx)以前版本的备份作为下一个版本的参考版本,就能很容易地避免产生版本树。
提示 如果一定要使用部件早期版本的源代码作为新部件的基础,那么应该重新给新部件的工程和可执行文件命名。
使用“工程兼容”时也可能产生版本树,所不同的是类型库的主版本号改变(而不是象图 7.4 中改变的是次版本号)。这对客户应用程序来说同样是灾难性的。
和使用“二进制兼容”一样,要避免这种情况,最好不拆分原来的树。如果在工程的某个阶段要用源代码的一个备份作为另一个部件的基础,那么新的工程应该使用不同的工程名和可执行文件名。
基于性能考虑,编辑时 Visual Basic 不会比较所有的接口。运行部件工程时,如果新版本和旧版本不兼容,Visual Basic 就会显示兼容性警告。(版本相同和版本兼容接口编译时无兼容性警告。)
注意 版本兼容性是以工程为基础来判断的。变动某个类模块中某个方法的声明部分,会使整个工程被标记为与以前的版本不兼容。可能导致版本不兼容的变动的列表,请参阅本章前面的“版本兼容性级别”。
假设向 Widget 对象的 Spin 方法添加了一个新参数。运行工程时会得到图 7.5 所示的警告。
图 7.5 版本不兼容警告
单击这条消息上的“声明”按钮可以查看旧的声明部分。如果是无意地做出变动,那么可以单击“编辑”打开代码并进行修改。
如果您选择接受警告,那么该部件将保留类型库标识符和类 ID。仅对于那些不再是二进制兼容的类的接口 ID 改变。这与工程兼容一致。
但是,如果您选择了忽略该警告,该部件仍然会保持该接口 ID。仅当编译器决定在某个方法的签名中有更改时,该选项可用。
小心 如果您绝对肯定所做的修改不会影响兼容性,那么应该只选择忽略警告。如果您不是绝对的肯定,请选择安全的替代方法。
重点 忽略编译器警告的选项代表了从 Visual Basic 5.0 以来行为的改变。在继续本选项之前,您要完全理解不兼容改变的含义,这一点非常重要。
如果没有修改工程名,那么在使用“生成 EXE 文件”命令时,将有警告消息提示应用程序和指定为参考版本的 .exe 文件不兼容,如图 7.6 所示。
图 7.6 .exe 文件不兼容的警告
这时单击“继续”创建的可执行文件可能会使客户应用程序出现故障。为使现有客户继续工作,在创建部件的不兼容版本时必须采取以下步骤:
在“二进制版本兼容性的级别”中详细讨论了这些步骤。
详细信息 有关该特性的主题列表请参阅“版本兼容性”。