MIDL and ODL
The Microsoft Interface Definition Language (MIDL) now includes the complete Object Definition Language (ODL) syntax. This allows you to use the 32-bit MIDL compiler instead of Mktyplib.exe to generate a type library and optional header files for a COM application.
Note
When the documentation refers to an ODL file, this means a file that Mktyplib.exe can parse. When it refers to an IDL file, this means a file that the MIDL compiler can parse. This is strictly a naming convention. The MIDL compiler will parse an input file regardless of its file name extension.
The topics in this section discuss using the MIDL compiler and IDL files containing both IDL and ODL statements to generate type libraries:
Generating a Type Library With MIDL
The top-level element of the ODL syntax is the library statement (library block). Every other ODL statement, with the exception of the attributes that are applied to the library statement, must be defined within the library block. When the MIDL compiler sees a library block, it generates a type library in much the same way as MkTypLib does. With a few exceptions, described in Differences Between MIDL and MKTYPLIB, the statements within the library block should follow the same syntax as in the ODL language and MkTypLib.
You can apply ODL attributes to elements that are defined either inside or outside the library block. These attributes have no effect outside the library block unless the element they are applied to is referenced from within the library block. Statements inside the library block can reference an outside element either by using it as a base type, inheriting from it, or by referencing it on a line as shown:
<some IDL definitions including definitions for interface IFace and struct bar> [<some attributes>] library a { interface IFace; struct this_struct; ... };
If an element defined outside the library block is referenced within the library block, then its definition will be put into the generated type library.
The MIDL compiler treats the statements outside of a library block as a typical IDL file and parses those statements as it has always done. Normally, this means generating C-language stubs for an RPC application.
For more information about the general syntax for an ODL file see ODL File Syntax.
Additional Files Required To Generate a Type Library
In order to compile an IDL file that contains a library statement, the OLE and OLE Automation DLL files must be on your system. These files are automatically installed with Microsoft Windows NT/Windows 2000 or Windows 95.
Effective with Windows NT 4.0, Oleaut32.dll supports a richer format for 32-bit type libraries. MIDL looks for this DLL on the build computer; if the new version is present, MIDL generates a new-format type library, otherwise it generates an old-format type library.
Note for 16-bit developers
If your application must interoperate with 16-bit applications, you must use the old-format type library for compatibility. The MIDL command-line option /old overrides this default and directs the MIDL compiler to generate old-format type libraries even if the newer version of Oleaut32.dll is present.
Some of the base types that MkTypLib supports are not directly supported in MIDL. MIDL obtains definitions for these base types by automatically importing Oaidl.idl whenever it sees a library statement. You need to ensure that this file is somewhere in your include path. The Oaidl.idl file, and the files that it imports (Objidl.idl, Unkwn.idl, and Wtypes.idl) are automatically installed when you install the Platform SDK.
See Also
Marshaling OLE Data Types, /old, /new
Differences Between MIDL and MkTypLib
There are a few key areas in which the MIDL compiler differs from MkTypLib. Most of these differences arise because MIDL is oriented more toward C-syntax than MkTypLib.
In general, you will want to use the MIDL syntax in your IDL files. However, if you need to compile an existing ODL file, or otherwise maintain compatibility with MkTypLib, use the /mktyplib203 MIDL compiler option to force MIDL to behave like Mkktyplib.exe, version 2.03. (This is the last release of the MkTypLib tool.) Specifically, the /mktyplib203 option resolves these differences:
typedef struct struct_tag { ... } this_struct; typedef struct { ... } that_struct;
If an optional tag is missing, MIDL will generate it, effectively adding a tag to the definition supplied by the user. Since the first definition has a tag, MIDL will generate a TKIND_RECORD for "this_struct" and a TKIND_ALIAS for "this_struct" (defining "this_struct" as an alias for "struct_tag"). Because the tag is missing in the second definition, MIDL will generate a TKIND_RECORD for a mangled name, internal to MIDL, that is not meaningful to the user and a TKIND_ALIAS for "that_struct". This has potential implications for type library browsers that simply show the name of a record in their user interface. If you expect a TKIND_RECORD to have a real name, unrecognizable names could appear in the user interface. This behavior also applies to union and enum definitions, with the MIDL compiler generating TKIND_UNIONs and TKIND_ENUMs, respectively.
MIDL also allows C-style struct, union , and enum definitions. For example, the following definition is legal in MIDL:
struct my_struct { ... }; typedef struct my_struct your_struct;
The following differences in behavior cannot be resolved by using the /mktyplib203 switch:
typedef struct { ... } a; enum {a=1, b=2, c=3};
[...]library A { typedef struct tagMOO {...}MOO } [...]library B { typedef struct tagMOO {...} MOO } [...]library C { importlib (A.TLB) importlib (B.TLB) typedef struct tagBAA {MOO y;}BAA }
The appropriate workaround for this is to qualify each such reference with the correct import library name, like this:
typedef struct tagBAA
{A.MOO y;}BAA
#define VOID void
See Also
/mktyplib203, /iid, Marshaling OLE Data Types
ODL Language Features in MIDL
The following topics list the Object Description Language (ODL) attributes, keywords, statements, and directives that are now part of the Microsoft Interface Definition Language (MIDL).
ODL Attributes
[appobject]
[hidden]
[propput]
[bindable]
[id]
[propputref]
[control]
[immediatebind]
[public]
[default]
[in]
[readonly]
[defaultvalue]
[lcid]
[requestedit]
[displaybind]
[licensed]
[restricted]
[dllname]
[nonextensible]
[retval]
[dual]
[odl]
[source]
[entry]
[oleautomation]
[uuid]
[helpcontext]
[optional]
[vararg]
[helpfile]
[out]
[version]
[helpstring]
[propget]
ODL Keywords, Statements, and Directives
coclass
library
dispinterface
module
enum
struct
[importlib]
typedef
interface
union
For information on how to marshal OLE Automation types, such as BSTR, VARIANT, and SAFEARRAY , see Marshaling OLE Data Types .
Generating a Proxy DLL and a Type Library From a Single IDL File
You can use a single IDL file to generate both the proxy stubs and header files for marshaling code, and a type library. You do this by defining an interface outside the library block and then referencing that interface from inside the library block, as shown in this example:
//file: AllKnown.idl [ object, uuid(. . .), <other interface attributes> ] interface IKnown : IUnknown { import "unknwn.idl"; <declarations, etc. for IKnown interface go here> }; [ <library attributes> ] library KnownLibrary { //reference interface IKnown: interface IKnown; //or create a new class: [ <coclass attributes> ] coclass KnowMore { interface IKnown; }; };