K & K Consulting    K & K Consulting

K&K Home VB Guru Home Search VB Site VB Code VB Tips VB Tutorials VB Questions

K&K Home
Up
VB Home

 

COM Binding Tutorial

 

Early Binding, Late Binding, Interfaces, Oh My!

The method you choose to bind to your external objects can make a huge difference on code size and execution speed. Naturally, early binding is much faster then late binding, but did you know that there is different ways to Early Bind? Did you realize one way is almost as slow as Late Binding? Well this tutorial will help you to understand the various ways to connect to external objects.

Interfaces

First of all, before you can understand binding, we should take a brief look at the COM interfaces and how they interact with your program.

In very loose terms, an interface is the part of the class exposed to you, the developer. Many developers incorrectly refer to the interface as all the exposed properties, methods and events of the class, although these things are part of the interface, they are not the interface it self.

All COM objects must expose the Interface IUnknown, IUnknown is the base interface for all COM interfaces exposed, and reside behind IUnknown in the interface hierarchy. IUnknown manages the lifespan of the COM object and handles client requests for interface access. To manage the COM object's lifespan, IUnknown maintains what is known as a reference count. The reference count is a tally of the number of active clients of a particular interface. Only when all of the reference counts for all of the interfaces exposed by a COM object reach zero, can the object be deleted and its memory safely freed. IUnknown.QueryInterface, is used to handle client access to COM objects. Clients gain access to a COM object by retrieving a pointer to one of the interfaces implemented by the object. To gain access to a particular interface, a client calls QueryInterface and sets the riid parameter to the identifier of the desired interface. So, in other words, the client calles QueryInterface to ask an object about the features it supports, and ask for pointers to specific interfaces. A large benefit of QueryInterface, is that without successfully calling QueryInterface first, you cannot possibly ask an object to perform any operation expressed through any interface. That is, in order to call an interface member function, you have to have a pointer to that interface. The only way to obtain such a pointer is by calling QueryInterface or by calling a creation function, which implicitly calls QueryInterface. If the object doesn't support the interface you request, it returns a NULL pointer, and you cannot make calls through a NULL pointer. Therefore, the object is always protected from malignant clients who think that they can bully objects into doing things the objects are not capable of doing.

Now, as a VB developer, you do not have to worry about all of this, the compiler will do all of the work for you, but, to be a VB Guru, you should understand how IUnknown and COM objects work.

Late Binding

Now that you understand how IUnknown works, let’s look at how Late Binding effect your application. Consider the following Late Binding Code:

Dim Foo as Object

Set Foo = CreateObject(“MyObject.MyClass”)

Foo.Name = “My Name”
Foo.DoSomthing

By setting Foo as an Object in the Dim statement, you are telling the compiler to hold a reference to an unknown object, so the compiler has absolutely no idea as to what that will be. The CreateObject function call will look up the ProgID in the system registry, load the object in memory (if it is not already their) and query IUnknown.QueryInterface for the interface pointers. Each call to the objects properties and methods require additional called to IUnknown for the appropriate DispatchID and then a final call to IUnknown with the DispatchID, and finally, execution of code.

Wow, that is a heck of a lot calling going on in the background, for just a small amount of code you wrote, and naturally it will slow down the application considerably. But, there are advantages to late binding. Consider the following:

Dim Foo as Object
Dim Retval as String

Retval = InputBox("Do You Want To Open Word or Excel")

Select Case Retval
Case is = “Word”
Set Foo = CreateObject(“Word.Application”)
Case is = “Excel”
Set Foo = CreateObject(“Excel.Application”)
End Select

As you can see, by late binding an object, you can have much more flexability in you application development.

Early Binding

Early Binding is the exact opposite of Late Binding, you tell the compiler exactly what to expect before compiling. You create a reference to the ProgID by setting a reference in the Project References menu. Consider the following Early Binding Code:

Dim Foo as MyObject.MyClass

Set Foo = New MyObject.MyClass

Foo.Name = “My Name”
Foo.DoSomeThing

During Compilation, the compiler does all the IUnknown stuff first and places the DispatchID’s etc. right in your compiled code. During code execution, IUnknown is called directly with the DispatchID, cutting down on the number of calls, thereby speeding code execution.

Now, the above example is the only one way of early binding, basically known as “Mid Level”, Early Binding. Did you know there is other ways too? Here are two more:

Dim Foo as New MyObject.MyClass

This is the fastest way for the developer, but the slowest in code execution. By creating this type of Early Binding, the compiler will add verification code before every call to your Foo Object, to verify that the pointer to the interface is valid. This will add tons of extra calls, meaning it is just slightly faster then late binding, and will increate the size of your final code.

The last type of Early Binding is called “Dual Interface” Binding. Most new compilers that can create COM Objects, Including VB6 can create, and Bind to, a “Dual Interface” Object. In this scenario, the Objects Interfaces are side-by-side to IUnknown and the client can call the Interface directly, skipping IUnknown all together. Although the code I supplied in the “Mid Level” example may use “Dual Interface” binding, it is not guaranteed to use it, the only way you are guaranteed, is to use the following example:

Dim Foo as MyObject.MyClass

Set Foo = CreateObject(“MyObject.MyClass”)

If the Object does not support a “Dual Interface”, the compiler will still use “Mid Level” Binding.

I know the CreateObject looks like it is using Late Binding, but you have already set a reference to the ProgID and Interface pointers with the Dim statement.

Well there you have it, as you can see, Binding can make a tremendous difference in you code size, speed, and behavior. So choose your Binding method carefully, but every Binding type has it’s place.





K&K Consulting's VB Guru, June 2000 

 

Send mail to WebMaster with questions or comments about this web site.
This website is best viewed with a screen resolution of 800*600 or better.
This website is optimized for Microsoft Internet Explorer 6.x
K&K Consulting, Proud to be a Microsoft Business Partner.
Last modified: January 31, 2002