Visual Basic Concepts

Maintaining Binary Compatibility

Visual Basic maintains backward compatibility by preserving class ID and interface ID information from previous versions of your component, as described in "Polymorphism, Interfaces, Type Libraries, and GUIDs," in "General Principles of Component Design." This information is not maintained in the type library, but is stored elsewhere in your component.

When a client application is compiled using a particular version of your component, the class ID and interface ID of each object it uses will be compiled in. When the client is run, the class ID is used to create an instance of the class, and the interface ID is used to verify that it’s safe to make the property and method calls that were compiled into the client.

If you make a new version of your component, using the Binary Compatibility option, the new version will contain the class IDs and interface IDs the old client needs to create objects and use their properties and methods, as well as class IDs and interface IDs of the enhanced versions of the classes.

New client applications compiled using the new version of your component can make use of the enhancements, because they compile in the new class IDs and interface IDs.

For example, suppose that in version 1.0 of your component, your Widget object has a Spin method, and that you’ve compiled a client application that creates a Widget object and calls the Spin method.

Now suppose you set the Binary Compatibility option and compile a new version of your component, in which the Widget object also has an Oscillate method. Visual Basic creates a new interface ID for the enhanced Widget. Because adding a method doesn’t break binary compatibility, Visual Basic also maintains the class ID and interface ID of the old Widget.

When your previously compiled application uses these old IDs, it gets an enhanced Widget — which is fine, because the new Widget still has the Spin method the old application needs to call.

Note   Binary Compatibility applies only to the default interface of a class — that is, the Public Sub, Function, and Property procedures you add to the class module. Interfaces you add using Implements are ignored.

Incompatible Interface Changes

Suppose that instead of adding an Oscillate method, you changed the arguments of the Spin method. For example, you might add a Direction argument.

If you could compile your component using the old class ID and interface ID for the Widget class, your old client application would be in trouble. It would be able to create the new Widget, but when it called the Spin method it would put the wrong arguments on the stack. At the very least, a program error would occur. Even worse, data could be corrupted.

Preventing Incompatibility

If you’ve selected the Binary Compatibility option, Visual Basic warns you when you’re about to compile an incompatible version of your component. You can reverse the edits that would make your component incompatible, or change the file name and Project Name so that the new version will not replace the old when users run Setup.

If you choose to disregard the warnings and compile an incompatible version of your component with the same file name and Project Name, Visual Basic may dump some of the interface IDs from previous versions of your component.

When the incompatible component is installed on a computer that has a client application compiled using an earlier version, it will overwrite the earlier version. Subsequently, when the client application attempts to create objects, it will receive error 430, "Class does not support Automation or does not support expected interface."

This averts more serious and subtle errors that might occur when the application attempts to invoke the properties and methods of the incompatible interface.

Limited Protection For Late-Bound Client Applications

Late binding is used when variables are declared As Object, because the compiler doesn’t know the class ID of the objects and interfaces that may be assigned to the variable at run time. Applications that use late binding create instances of your classes using the CreateObject function and the programmatic ID, as shown here:

Dim obj As Object
Set obj = CreateObject("MyComponent.MyObject")

The CreateObject function looks up the class ID in the Windows Registry, and uses it to create the object. Thus it will always create the most recent version of the object.

As long as you preserve binary compatibility, late-bound clients will continue to work successfully with your component.

If you make an incompatible version of your component using the same programmatic IDs for your objects, late-bound clients can still create the objects, because they’re looking up the class ID instead of having it compiled in. When they call methods whose arguments have changed, or methods you’ve deleted, program failure or data corruption may occur.

For More Information   See "Levels of Binary Version Compatibility" for a description of the degrees of compatibility employed by Visual Basic. See "Version Compatibility" for a list of topics related to this feature. See "Polymorphism, Interfaces, Type Libraries, and GUIDs," in "General Principles of Component Design" for background information and concepts.