Visual Basic Concepts

Using Binary Version Compatibility

Whenever you begin work on a new version of an existing component, you need to specify a type library which Visual Basic can use as a reference point for determining compatibility. In most cases, this will be the type library included in executable (.exe, .dll, or .ocx file) for the last version of the component you distributed.

Each time you build an interim version of your updated component, Visual Basic extracts information about the old interfaces from this .exe file and compares it to the new interfaces of your class modules.

"Providing a Reference Point for Compatibility" explains the procedure for creating a reference point.

Keeping the Reference Version Separate from Interim Builds

Important   Keep the copy of the .exe file you specify as your reference version separate from the build copy of the new version.

Each time you make an interim build, Visual Basic adds a new set of interface identifiers to the executable, one identifier for each class module. If you specify your build copy as the reference version, it will accumulate a complete set of interface identifiers for every version-compatible interim build you have ever done. (Interface identifiers do not change for version-identical builds.)

In addition to the sixteen bytes taken up by each interface identifier, having unused interface identifiers in your executable — only your test applications ever use the interim versions — can slow down cross-process access to your component in some situations, and the Windows Registry of any computer your component is installed on will be cluttered with unused interface identifiers.

If your reference version is a copy of your last released executable, all your interim builds will have the same interface version number, and your final build will have only the interface identifiers it needs: all the sets from the reference version (to provide backward compatibility) plus the set of interface identifiers for all the classes in your new release.

Note   When you’re developing the first version of a component, using Project Compatibility instead of Binary Compatibility, exactly the opposite is true: The reference version should be your interim build. This does not bulk up the type library, because Project Compatibility never saves the interface identifiers.

Avoiding Version Trees

Because Visual Basic produces the version number for the new type library by incrementing the type library version number it finds in the reference version, the released versions of your component form a chain, each link derived from its predecessor. As mentioned earlier, each new release contains all the interface identifiers for preceding versions, so that a client application compiled with any previous version will still work with the latest.

What’s a Version Tree?

Version trees arise when your component’s version history acquires branches — that is, when you produce two physically distinct components based on the same source code. It’s important to keep the version history of your component straight, and avoid such branching.

Figure 7.4 shows some of the problems that can be caused by version trees. (The version numbers are for illustrative purposes only, and are not intended to represent actual type library version numbers.)

Figure 7.4   Problems with version trees

The long branch at the right shows four successive versions of a component executable, and a new executable that has been created by adding to the source code for the executable whose type library version is 1.3.

The correct continuation of this version history is for the latest executable to be compiled with the version 1.3 executable as its reference version. The new type library version number is 1.4. The .exe file maintains compatibility with client applications compiled using any of its predecessors.

Because it’s at the end of a chain of compatible versions, the new executable could also be compiled with the version 1.0 executable as its reference version. In this case, its type library version number will be 1.1. This could cause problems for clients compiled to take advantage of features of the new version. If they’re placed on a computer with the earlier version 1.1 executable, the new features will not be available, and the applications will fail.

A different problem arises when the new component is installed on computers that have client applications compiled with type library version numbers 1.1, 1.2, and 1.3. Standard practice is to increase the file version number of each new executable file, to ensure that Setup will replace earlier versions of the executable. (Remember that file version numbers are independent of type library version numbers.)

Thus the new executable, containing interface identifiers for type library versions 1.0 and 1.1, will replace older executables that contained interface identifiers for type library versions 1.0 through 1.3.

If the computer already has client applications compiled with type library versions 1.2 and 1.3, those clients will be unable to use the new version of the component.

Divergent Versions

The left side of the tree shows divergent versions. This can arise when the source code for an early version of your component is taken as the basis of a new component, and classes are added that do not exist in your main version history.

If the executable for your component is used as the reference version for the divergent version, the type library version numbers of the divergent version and its successors will overlap the version numbers of your components. The results for client applications will be disastrous.

Tip   You can easily avoid the creation of version trees by always setting aside a copy of the previous version of your component’s executable file (.exe, .dll, or .ocx) as the reference version for the next release, as described earlier in this topic.

Tip   If you decide to use the source code of an earlier version of your component as the basis of a new component, give the new component a different project name and executable name.

Version Trees with Project Compatibility

Version trees can also arise when you’re using Project Compatibility, the difference being that it’s the major version number of the type library that changes (instead of the minor version number, as shown in Figure 7.4). The consequences to client applications can be equally disastrous.

As with Binary Compatibility, the best way to avoid this is not to split your source tree. If you take a copy of your source code at a particular stage of the project as the basis for another component, use a different project name and executable name for this new project.

Version Compatibility Messages

For performance reasons, Visual Basic does not fully compare interfaces as you edit. When you run your component project, Visual Basic will always display a compatibility warning if the new version is incompatible with the old. (Version-identical and version-compatible interfaces will compile without compatibility warnings.)

Note   Version compatibility is judged on a project-wide basis. A change in the declaration of just one method in one class module causes the entire project to be marked as incompatible with the previous version. See "Levels of Version Compatibility," earlier in this chapter, for a listing of changes that will cause a version incompatibility.

Version Incompatibility Warnings

Suppose you add a new argument to the Spin method of the Widget object. When you run the project, you’ll get a warning that binary compatibility has been broken. You can examine the old declaration by clicking the Declaration button on this message. If you made the change accidentally, you can click Edit to bring up the code and fix it.

If you choose to accept the warning, the component will retain the type library identifier and the class IDs. Interface IDs are changed only for classes that are no longer binary compatible. This is the same behavior as Project Compatibility.

If, however, you choose to ignore the warning, the component will also maintain the interface IDs. This option is only available when the compiler determines that there was a change in the signature of a method.

Caution   You should only choose to ignore the warning if you are absolutely sure that the changes you have made won't break compatibility. If you aren't absolutely sure, take the safe alternative.

Important   The option to override the compiler's warning represents a change in behavior from Visual Basic 5.0. It is important that you fully understand the implications of incompatible changes before proceeding with this option.

Incompatible EXE File

If you have not changed the project name, when you use the Make EXE File command, you will get a warning that your application is incompatible with the .exe file you specified as your reference version, as shown in Figure 7.5.

Figure 7.5   Warning for incompatible .exe file

Clicking Continue at this point creates an executable file that could cause existing client applications to fail. In order for existing clients to continue working, you must take the following steps when you create an incompatible version of a component:

  • Change the file name.

  • Change the project name.

  • Compile with Version Compatibility set to No Compatibility.

These steps are discussed in detail in "Levels of Binary Version Compatibility."

For More Information   See "Version Compatibility" for a list of topics related to this feature.