- A type library is a runtime interface that describes the contents
of a DLL.
- They describe C structures, enumerated types, functions, paramaters,
C++ data structures and classes, COM
interfaces, and OLE Automation dispatch interfaces.
- There are two interface definition languages for creating type libraries:
ODL and MIDL.
- From "Inside OLE, Second Edition", p. 181:
- Whatever you can store in header files (.H), import libraries (LIB
files for linking to DLL expored functions), and
indexes to help files (HLP), you can store and retrieve through type information.
- Any compiler or late bound programming environment can use the information
as it would a header file (even precompiled), or an import library.
- Alternative ITypeLib and ITypeInfo Implementations:
There is nothing sacred about OLE's type information services that provide
the standard implementations of type library and type infomation objects.
You are perfectly free to implement your own objects with these interfaces
that sit on top of a type library. Such custom implementations might be
used to extend the available information for the purposes of a particular
client. For example, if you want to extend the properties available on an
object with a set of client-supplied properties and to use type information
consistently throughout the controller, you can implement wrapper interfaces
that filter out the specific client types before passing the calls on to
OLE's standard implementations.
- Type information is considered the essence of OLE Automation, invented
out of sheer necessity for OLE's purposes. However it's useful for many
other purposes, and has now heavily used by Connectable Objects and OLE
- A type library is nothing more than a collection of static data
structures for each element within it, and those structures contain additional
nested structures to describe their contents. In this sense, the library
itself is not an "object," as it doesn't have any inherent functionality.
OLE provides the wrapper objects -- its type library service with appropriate
interfaces -- to let you work with these underlying structures without having
to know the exact structures themselves. Because interfaces are language-independent
constructs, OLE's services here are usable from any client and can be used
to describe any object, regardless of implementation.
- Type Library Elements:
- coclass: describes the interfaces and dispinterfaces implemented
on a particular object (identified by a CLSID).
- interface: Describes a vtable interface (identified by
an IID): specifically, the names of the member functions, the return types
of those functions, and the names and types of the arguments to those functions.
- dispinterface: Describes a dispatch interface (identified
by an IID) used by OLE Automation: specifically, the names, dispIDs, and
types of the methods and properties (including return types and argument
names and types for methods in the interface).
- module: Describes a DLL module (identified by a DLL filename),
including names and ordinals for exported functions and global variables.
- typedef: Describes a user-defined data structure, enumeration,
or union (identified by a name or an optional GUID).
- Type Library and Element Attributes:
- Name: Descriptive name of type library or element without
spaces or punctuation. Every element has a name.
- GUID (or UUID): A programmatic identifier for the library
or element. A library GUID is different from other CLSIDs or IIDs. A module
cannot have a GUID; it is optional for a typedef; it is required for all
- Version: The major and minor version of the library or
- DocString: A short piece of text describing the purpose
of the library or element.
- HelpFileName: The name of a help file (no paths) that contains
further information about all the contents of the library. There is only
one help file per library, so this attribute applies only to a library and
not to individual elements.
- HelpContext: The context ID inside HelpFileName, where
specific information is found for library or element.
- LCID: A locale identifier, or locale, that describes the
single national language used for all text strings in the type library and
elements. A type library is intended to be written for a specific national
language, with the exception that individual function arguments can be given
a locale for the purpose of accommodating functions that might perform translations.
- Flags: Bits specifying additional aspects about the library
or element. Although there are many element flags, a library has only a
few possi bilities: no flags at all, hidden (not browsable through user
interface), or restricted (controlled programmatically for security).
- Creating Type Libraries: There's a CreateTypeLib function
that makes a new type library file and returns an ICreateTypeLib
interface, through which you can manipulate the type library. You can set
the type library attributes, and create TypeInfo elements, by calling the
CreateTypeInfo function, that takes an element type and a name, and returns
an ITypeInfo interface. When you are done adding elements to the
library, then you can save all changes.
- The ITypeInfo interface lets you set the attributes of the
element, and fill in other information and sub-elements required by the
various element types.
- The easy way to make type libraries is by using the MKTYPLIB
program to compile an ODL interface description.
- In the new version of OLE for Windows
NT 4.0, ODL has been replaced by the newer MIDL
3.0, that unifies the two interface description langauges.
- Dual Interfaces: This is when you have a COM
interface, as well as a corresponding dispatch interface, for the same functionality.
Dual interfaces are now recommended over the definition of a dispinterface
from an interface. It makes it possible to use an object more efficiently
via COM or more flexably via OLE Automation.
- You can distribute type libraries in several ways: attached to the
component's server module (EXE or DLL) as a resource, stored in a stream
named "\006typelib" (located in the root storage object) in a
compound file, or in a stand-alone TLB file.
- The registry has a TypeLib section indexed
by LIBIDs that keeps track of where all the type libraries are, as well
as their version number, locale information, and help directory.
- A practical use of type information outside the scope of an instantiated
object is for things called type infomation browsers. Type information browsers
can look inside type libraries and present the available objects, interfaces,
methods, and properties to an end user. These browsers can be the basis
for powerful environments that might use drop-down list boxes and drag and
drop in their programming user interfaces, greatly reducing the amount of
typing that a programmer must do manually. I have not seen this sort of
tool at the time of writing this text; I hope to see such innovative work
in the future. However, two tools in the OLE SDK provide some sort of browsing
capability. The first is TIBROWSE, for which the source code is provided
as a sample. (It is also in Microsoft Visual C++.) This is a pretty simple
tool, but it gives you the idea. A more complete tool, for which souces
might not be provided, is OLE2VIEW. This tool allows you to peek into type
libraries, among other things, through its File/View Type Library command
or by locating a type library in OLE2VIEW's display of the registry. OLE2VIEW
will show you just about everything that's in a library and can be very
useful as a browser. (p. 174)
- The ITypeComp interface is for compilers to efficiently retrieve
the type information they need from type libraries, without going through
all the effort of navigating through the ITypeLib and ITypeInfo interfaces.
- The IProvideClassInfo interface is how an instantiated object can
directly provide type information to other clients. If it wants, it can
implement this interface, so clients that need that information to not have
to look up the object's CLSID and navigate through the type library manually.
The only kinds of object that are currently required to implement the IProvideClassInfo
interface are objects with custom event sets, such as OLE Controls. For
other objects, it's merely a convenience for interested clients, but recommended.
Essentially, the IProvideClassInfo interface represents the ability of an
object to describe its interfaces and types when everything else about it
is unknown. The only deficiency in this interface is that it's impossible
to ask for type information in a particular language.
- Some structures related to type libraries and elements:
- TLIBATTR: contains a type library's LIBID (GUID), LCID, version
numbers, flags, and target OS
- TYPEKIND: Enumerates the type of a particular element in the library.
- TYPEATTR: Contains the attributes of any TYPEKIND element: GUID
(IID, CLSID, etc.), LCID, member IDs of constructor and destructor methods
(interface and dispinterface), size of an instance of the type, count of
methods (dispinterface), count of properties, variables, and data members
(interface and dispinterface, typedef), count of interfaces (for coclass),
size of the vtable (interface and dispinterface), byte alignment, and version
number. Also included are TYPEDESC, TYPEFLAGS, and IDLDESC fields.
- TYPEDESC: describes the type of a variable or argument or the
return type of a method. Nested TYPEDESCs describe nested structures.
- ARRAYDESC: Describes an array of some type with a specific number
of dimensions and the bounds of each dimension.
- HREFTYPE: A handle (unsigned long) that identifies a TYPEDESC.
- TYPEFLAGS: An enumeration containing various flags.
- IDLDESC: Structure containing information used in marshaling an
- IDLFLAGS: An enumeration that identifies an argument as having
the in or the out attribute, both attributes, or neither attribute.
- ELEMDESC: A structure that describes a typedef enum using a TYPEDESC
and an IDLDESC.
- FUNCDESC: A structure that describes a method, including its dispID,
an array and count of legal return SCODEs (success result codes), the type
of function (FUNCKIND), flags (FUNCFLAGS), the invocation style (INVOKEKIND),
the calling convention (CALLCONV), the number of total arguments, the number
of optional arguments, an array of ELEMDESC structures for each argument,
the ELEMDESC of the return type, and the offset of this method in a vtable.
- FUNCFLAGS: An enumeration that contains various flags.
- FUNCKIND: An enumeration that describes the function as either
FUNC_VIRTUAL (called by an offset in a vtable), FUNC_PUREVIRTUAL, FUNC_NONVIRTUAL
(called by address and takes a "this" pointer), FUNC_STATIC (called
by address and takes no "this" pointer), or FUNC_DISPATCH (member
of a dispinterface called through IDispatch::Invoke).
- CALLCONV: An enumeration that identifies the types of operations
available through IDispatch::Invoke: INVOKE_FUNC, INVOKE_PROPERTYGET, INVOKE_PROPERTYPUT,
INVOKE_PROPERTYPUTREF. These map exactly to DISPATCH_* values.
- IMPLTYPE: Am enumeration containing the implementation type of
interface or dispinterface in a coclass: IMPLTYPE_FDEFAULT, IMPLTYPE_SOURCE,
- VARDESC: A structure that describes a variable, argument, constant,
or data member and contains a dispID (MEMBERID), an offset of the variable
within an object instance or a VARIANT with the actual value of a constant,
an ELEMDESC, a value from VARFLAGS, and a type from VARKIND.
- MEMBERID: Same as a dispID.
- The ITypeInfo interface:
- GetContainingTypeLib: Retrieves the ITypeLib interface for the
library that contains this type information as well as the index of this
type information in the library.
- GetDocumentation: Given an index, returns the item name and help
- GetFuncDesc: Allocates, fills, and returns the FUNCDESC structure
for a method with a given index in an interface.
- ReleaseFuncDesc: Gets rid of a FUNCDESC.
- GetNames: Retrieves the names of properties, types, variables,
methods, methods arguments, and so forth.
- GetIDsOfNames: Maps text names of a dispinterface to dispIDs and
- GetRefTypeInfo: Returns the ITypeInfo of a given HREFTYPE.
- GetTypeAttr: Allocates, fills, and returns the TYPEATTR structure
for this ITypeInfo.
- ReleaseTypeAttr: Gets rid of a TYPEATTR.
- GetRefTypeOfImplType: Returns the HREFTYPE for an interface or
dispinterface in a coclass.
- GetImplTypeFlags: Returns the IMPLTYPE flags of an interface or
dispinterface item if it's in a coclass.
- GetVarDesc: Allocates, fills, and returns a VARDESC structure
describing the specified variable.
- ReleaseVarDesc: Gets rid of a VARDESC.
- Invoke: Invokes a method or accesses a property of an object that
implements the interface described by this ITypeInfo.
- CreateInstance: Attempts to create a new instance of a coclass
using CoCreateInstance for the UUID attribute.
- AddressOfMember: Retrieves the addresses of static functions or
variables defined in a DLL as well as the INVOKEKIND flag.
- GetDllEntry: Retrieves the DLL module name and function name (or
ordinal) of an exported DLL function as well as its INVOKEKIND flag.
- GetMops: Retrieves marshalling information for an argument.
- GetTypeComp: Returns the ITypeComp interface for this ITypeInfo.