The ITypeComp Interface

If you've ever looked into type information before reading this chapter, you're probably still confused to death about this ITypeComp interface—like, what it's for in the first place and what you're supposed to do with it.8 The name of the interface implies the type of client that might use it: "Comp" stands for "compiler." A compiler can use type information as a sort of header file or as an import library.

During the compilation process, compilers need to quickly access information about user-defined types, exported module functions, global variables and constants, and interfaces within coclass objects. The optimization, which works through ITypeComp::BindType and ITypeComp::Bind (the only two members besides those in IUnknown), allows the compiler to quickly locate this information without having to navigate through all the elements over and over, which would be tremendously slow. Bind is also what gets you the FUNCDESC or VARDESC structure for a variable, constant, or exported function.

Navigation through the entire library according to its structure makes perfect sense for a type information browser, for which the locations of the data in question are important. But for a compiler, location in the structure isn't of any concern—it's the data itself that's important. For example, if you wanted to locate an exported function named arctan in some modules that are described in a type library, you could call ITypeLib::GetTypeComp and then ITypeComp::Bind. This procedure is much easier and faster than calling ITypeLib::FindName, ITypeLib::GetTypeInfo, ITypeInfo::GetIDsOfNames, and ITypeInfo::AddressOfMember, which would accomplish the same end. If you wanted to restrict the search to a single object class, you can call ITypeInfo::GetTypeComp by using the ITypeInfo for that coclass. The ITypeComp you get in this case would ignore everything else in the library, for an even faster search.

Both Bind and BindType, as well as ITypeLib::FindName and ITypeLib::IsName, involve the use of a hash value for the name in question. The OLE API function LHashValOfName does the actual hashing. LHashValOfName is a macro that is converted to a call to LHashValOfNameSys inside the OLE header files, so you don't have to care what system you're working on. (The system is hard-coded into the header files for each system, which is appropriate.) In any case, before calling Bind or BindType, you hash the name you're looking for by using this function and pass it as an argument to the ITypeComp functions, which then race through the library looking for a match, bypassing all the tedious navigation through the various elements.

8 I am indebted to Burt Harris for greatly clarifying the purpose of this interface to me.