only for RuBoard - do not distribute or recompile |
One of the details VB hides from the programmer is the fact that an interface and a class are two distinct entities. This is easier to visualize once you know what a class really looks like; Figure 2.1 attempts to depict the Cow class graphically. A class is nothing more than a pointer to an array of function pointers (member functions), followed by public and private data. This array of function pointers is called a virtual function table , or vtable . This arrangement allows multiple instances of a COM component to share the same vtable, which is very efficient in terms of memory. Of course, member variables are not shared. Every instance of a component has its own copy of any public or private member variables . Also, if a class such as Cow had any methods of its own or implemented any additional interfaces, these would be added to the vtable. The order of a vtable is very important, because for all practical purposes the vtable is the physical representation of the interfaces an object has implemented.
The Animal and Cow interfaces are unique. Behind the scenes, VB has assigned a globally unique identifier (GUID) to both of these interfaces. A GUID that names an interface is called an IID. The IID for Animal is {101E95AB-018E-11D3-BB7C-444553540000}. Well, actually this is a string representation of an IID. An IID is a unique 128-bit number, and it is this value that is the true name for the Animal interface. After all, there's nothing really unique about the name Animal . What if another developer on the other side of the world wanted to create an interface named Animal with different attributes? GUIDs are how COM guarantees that an interface is unique, and this allows two interfaces with the same name to coexist peacefully on the same machine.
|
You can find IIDs in the registry under HKEY_CLASSES_ROOT\Interface .Figure 2.2 shows the Animal interface in the registry.
Because the key name is the IID itself, you will have to do a search on the interface name to find it.
Once an interface has been published, COM states that the interface is immutable. You never modify an old interface, you just create a new interface. In other words, the IID that is the Animal interface should always have three methods: Kingdom , Name , and Noise . These three methods will always be argument free and always return the types Kingdoms, String, and String, respectively. If any aspect of this interface changes, the contract is broken, and clients that relied on that interface will be broken; therefore, old interfaces are never modified.
If it became necessary to add functionality to the Animal interface at some future date, the rules of COM state that a new interface should be created (i.e., Animal2 ). This is one of the fundamental tenets of COM: rather than modifying an existing interface, a new interface is created instead. It is important to note that when the new interface is created, the old interface is left in place. Interfaces should never be deleted. This ensures that clients using the original interface will continue to work and that clients that are aware can take advantage of the features the new interface offers.
In addition to creating interface definitions, VB generates a co-class for Animal and Cow . A co-class is similar to an interface, but instead of method and property definitions, it contains a list of the interfaces a component supports. It is a component definition. This is what defines the Animal and the Cow in terms of what interfaces each component supports and the vtable order of those interface methods. Like interfaces, co-classes also have a unique GUID that represents the object. This identifier is called a CLSID. As an IID is the true name for an interface, a CLSID is the true name for the entire component itself. The easiest way to find a CLSID is to first look up the programmatic identifier, or ProgID, of the component. A ProgID is a string that VB creates from the project name and the class name. In the case of our Animals component, the ProgID for Cow would be Animals.Cow . The ProgID and the CLSID representing the component can be found in the HKEY_CLASSES_ROOT branch of the registry, as shown in Figure 2.3.
Once you have obtained the CLSID for an object, you can find its entry under HKEY_CLASSES_ROOT . Notice the InprocServer32 key. This is how the ProgID, say in a call to the VBA CreateObject function, is mapped to the physical location of the component.
Version CompatibilitySpecific identifiers are used throughout this book. If you register the components provided with each chapter, your registry settings will mirror the examples used in this book. If you compile the code yourself, the identifiers will be different. There is a way to enter and compile all the source and have the identifiers match the examples found in this book. You can do this by setting the version compatibility for your projects to Binary Compatibility. Version compatibility settings are found on the Component tab of the Project Properties dialog. There are three different types of version compatibility that you can specify for your COM projects:
|
only for RuBoard - do not distribute or recompile |