Before explaining the concept of binding, and describing the differences of early and late binding, the following mantra should be memorised and chanted religiously on a daily basis:
Late Binding is Slow and Bad. Early Binding is Fast and Good.
If nothing else, then remember this.
Now onto the explanation.
When a Visual Basic program calls a subroutine, or a method or property of an internal Private class, what this effectively compiles down to is a single assembly language subroutine call instruction, albeit surrounded by error and parameter handling code. Subroutine calls are therefore very fast.
When calling a method or property of an in-process COM component using early binding, the call effectively compiles down to a single indirect assembly language subroutine call, with surrounding error and parameter handling code. This is only very slightly slower than a straight subroutine call. The process goes roughly according to the steps given below.
This explanation is vastly over-simplified, and not 100% accurate, but does serve to explain the basic principle.
A design time reference to the component to be accessed is made, using the ‘Project, References’ menu item. In this way the registry can be accessed (which contains information about the component) and all the ClassIDs, and available methods, properties, and their parameters can be determined.
When an instance of the class is required, the declaration of the object should then be explicitly cast as the class of the object to create, for example:
Dim oObject As MyProj.MyClass
’
Set oObject = New
MyProj.MyClass
oObject.MyMethod
Because the compiler knows all about the methods and properties supported by the MyClass class, and knows that the oObject object represents an instance of this class, it is able to construct the call to MyMethod as an indirect call into a lookup table using an index representing the MyMethod method. At run-time, when the oObject object is created, the MyProj DLL is loaded, and the lookup table completed with the addresses of code segments to be called for each of the methods of the MyClass class. This form of binding is also sometimes termed Vtable binding.
Early binding also applies to calls to out-of-process components. Obviously these calls cannot be implemented as indirect assembly language calls as the destination code is executed in a different process. However, the concepts are similar, and it remains true that early binding is significantly faster than late binding even when accessing out-of-process components.
In a late binding scenario, there is no need for a design-time reference to the COM component to be created, and when an instance of a class is required, the declaration of the class need not be explicit, for example:
Dim oObject As Object
’
Set oObject =
CreateObject(”MyProj.MyClass”)
oObject.MyMethod
Note the following code segment:
Dim oObject As Object
’
Set oObject = New
MyProj.MyClass
oObject.MyMethod
This code segment is valid if a design time reference to the MyProj class component has been made. However, even though the CreateObject function is not used, it is effectively functionally the same as the first example, and will use late binding since the oObject variable is typed as an Object. This is a common coding error made by inexperienced Visual Basic COM programmers.
In this late binding scenario, the compiler knows nothing about the MyClass class, since there is not necessarily a reference to the component, and does not know what class the oObject is an instance of, since as an Object type it could be used to hold instances of any object. Working out what to do when the MyMethod method is called must then be deferred until run-time, when the line is actually executed.
Effectively what happens is that the registry is string searched for a reference to the ‘MyProj.MyClass’ string in order to locate the ClassID, Once this is determined, methods on a special interface supported by the class are called in order to determine what code to actually execute. Again, this uses string searching to locate the ‘MyMethod’ call.
It is because late binding uses so much string and registry searching, and additional COM calls that it is so much slower than early binding.
The interfaces used to support late binding are called IDispatch and IUnknown. Support for these is handled automatically by Visual Basic, and is of no concern.