Chapter 3 Type Information

SETTING THE CLOCK

Complete these steps to set the clock:

1. If the display does not show the clock, press F/C.

2. Press and hold down F/C.

3. While holding down F/C, turn TUNING counterclockwise until the display shows the correct hour.

4. While holding down F/C, turn TUNING clockwise until the display shows the correct minute.

5. When the display shows the correct time, press F/C.

Car stereo owner's manual

A few months ago, I finally decided to replace the broken radio/tape deck in my 1976 Datsun 610, as moving to a new house had lengthened my commute considerably. After a lot of scouting around, I found what I was looking for on one of those half-price discount tables in front of the local Radio Shack—you know, the ones with the unidentifiable bare circuit boards and the leftover firefighter's hats with the siren and the flashing red light. Anyway, I sorted through the box, and everything seemed to be there: the stereo, knobs, speaker cables, and so on. I took the radio/tape deck home and disassembled my car's dashboard (that's what you have to do with an old Datsun, which makes it damn hard for anyone to steal the stereo), and after the better part of a day I had it all in there and working. Installation was straightforward enough, and some of those electrical engineering classes I had in college seemed to pay off. The wiring "interface," if you will, was readily apparent, so I didn't bother to refer to the owner's manual.

It was only when I got around to setting the clock on this device that I discovered that I did not, in fact, have an owner's manual. I tried quite a number of button combinations, but nothing worked. Showing my lack of skill as a thorough tester, I gave up and returned to Radio Shack to get a manual. The sequence of steps required to set the clock had never occurred to me: my digital-electronics mindset told me that pressing buttons was the way to change a digital clock, rather than turning the seemingly analog (but really digital) knobs. Once I had the information, however, it seemed perfectly reasonable, and I was able to set the clock.

The point of this story is that in order to use the device properly, I needed something other than that device's own interfaces to tell me what I could do with it. The same is true of COM and OLE objects: given some arbitrary IUnknown pointer, there are limitations to what you can discover about an object. Just as I didn't want to spend the time articulating and attempting every possible combination of pressing buttons and turning knobs to set the time on my clock, clients generally do not want to spend the time querying an object for every possible interface just to figure out which interfaces exist. Such an operation is not exactly high performance. Furthermore, merely being told that an object has an interface doesn't tell you much about how to make calls to the interface; for example, knowing a specific function's offset in the interface vtable and what types of arguments it takes (the stack it expects) is not enough information to be able to reliably call the function. Knowing that there is an interface is about as informative as knowing that setting the clock involves one of the buttons and one of the knobs. It would have helped a little, but not completely. I really needed the owner's manual.

The rough analog of an owner's manual for an object is type information. An owner's manual tells me how to do something once I know that I want to do it—that is, it tells me how to carry out my intentions. In the same fashion, type information contains the necessary information about objects and their interfaces—for example, what interfaces exist on what objects (given the CLSID), what member functions exist in those interfaces, and what arguments those functions require. Type information can also describe custom types such as C-style data structures, unions, and enumerations, as well as noninterface functions that are exported from a DLL module. In fact, whatever you can store in header files (H), import libraries (LIB files for linking to DLL exported functions), and indexes to help files (HLP), you can store and retrieve through type information.

Type information, however, does not tell a client why it would want to look at an object's interfaces or call member functions, nor does it say when such things should take place. My car stereo owner's manual, in the same way, doesn't tell me why I want to set the clock or when I should do it; it only says how. With my car stereo and components alike, the intent of using that information exists externally, usually in the head of some human. With our current computer sophistication, only portions of that intent can be incorporated into running client code. Therefore, type information is most useful when a human can browse it and tell some client when to use which object and what member function, and what to pass those member functions. In other words, in our current technology it generally takes a human to interpret what the information means and why and when it's useful. We'll leave it to the artificial intelligence community to figure out how to get a computer to do the same.

In the meantime, plenty of useful things can happen with type information that involve interactive development tools: a developer can browse available objects, look at their interfaces and member functions, and potentially do point-and-click programming rather than text-based coding. But type information is not just for browsing: any compiler can use the information just as it would use a header file (even precompiled) or an import library, in the same way any interpreted or otherwise late-bound programming environment can.

In this chapter, we'll look at what type information is, what it can contain, and the basics of how you work with it, both in creation and in manipulation. Type information is an OLE-provided and OLE-implemented service involving a number of API functions that create and load the information as well as a number of interfaces through which you store and retrieve information. We introduced a few of these—such as ITypeLib and ITypeInfo—in Chapter 1. Here we'll explore them in more detail, although we won't actually see them used in code until later chapters, which cover topics for which type information is necessary. Hence this short chapter contains no samples.

OK, this sounds great, but you're likely not in the business of creating development tools, right? So why am I bothering to tell you about this stuff? Why is it so important that I put it here at the front of this book, in Chapter 3, without any samples? There are two reasons.

First, type information has been considered part of OLE Automation for a long time. Some have called it the essence of Automation. It was, in fact, invented out of sheer necessity for Automation's purposes. However, the technology itself has begun to assume a wider and more general role in the whole of OLE and thus has many uses entirely outside of Automation. Type information is now used heavily in a number of other important OLE technologies—for example, Connectable Objects and OLE Controls. Because type information is used so widely and can be used with any other OLE technologies (although it's not required with others as it is with Automation), what we learn here will enable us to talk about "an object's type information" in later chapters with a full understanding of what it means. I'd rather not break up our discussions about other technologies with distracting excursions into details of type information. Rather than spreading the details throughout this book, I've centralized the information here, even though some parts of it won't mean much until we look at them in context with the OLE technologies that care.

Second, because you can store so much rich type information, the technology involved will become vitally important in the next generation of development tools that are centered on the creation of applications from components rather than from source code. These tools will depend on an object's type information to show the developer what an object can do and what you might be able to connect with it. Rather than the tools having to try to read basically unstructured header files and help files, they'll use type information, which is stored in a structured, language-independent repository and is accessed through various OLE-implemented objects and their interfaces. Thus, the tools don't need to have language-specific parsers and can use other components written in any language.

When applications can be created with components instead of code, I personally believe that we'll see many more opportunities for growth in the computer industry, perhaps even a significant area of tools that enable end users to effectively "program" their own custom applications and solutions, although the users won't call it programming—they'll call it fun. But component integration tools cannot happen if components are as mysterious as the clock setting feature on my car stereo. Type information is how you publish your owner's manual.