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 MKTYPLIB.EXE, version 2.03. (This is the last release of the MKTYPLIB tool.) Specifically, the /mktyplib203 option resolves these differences:
In MKTYPLIB, both of the following definitions generate a TKIND_RECORD for "bar" in the type library. The tag "foo" is optional and, if used, will not show up in the type library.
typedef struct foo { ... } bar;
typedef struct { ... } bar;
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 "foo" and a TKIND_ALIAS for "bar" (defining "bar" as an alias for "foo"). 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 "bar". 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 foo { ... };
typedef struct foo bar;
In MKTYPLIB, the boolean base type and the MKTYPLIB data type BOOL equate to VT_BOOL, which maps to VARIANT_BOOL, and which is defined as a short. In MIDL, the boolean base type is equivalent to VT_UI1, which is defined as an unsigned char, and the BOOL data type is defined as a long. This leads to difficulties if you mix IDL syntax and ODL syntax in the same file while still trying to maintain compatibility with MKTYPLIB. Because the data types are different sizes, the marshaling code will not match what is described in the type information. If you want a VT_BOOL in your type library, you should use the VARIANT_BOOL data type.
In MKTYPLIB, GUIDs are defined in the header file with a macro that can be conditionally compiled to generate either a GUID predefinition or an instantiated GUID. MIDL normally puts GUID predefinitions in its generated header files and GUID instantiations only in the file generated by the /iid switch.
The following differences in behavior can not be resolved by using the /mktyplib203 switch:
In MKTYPLIB the scope of symbols in an enum is local. In MIDL, the scope of symbols in an enum is global, as it is in C. For example, the following code will compile in MKTYPLIB, but will generate a duplicate name error in MIDL:
typedef struct { ... } a;
enum {a=1, b=2, c=3};
If you apply the public attribute to an interface block, MKTYPLIB treats every typdef inside that interface block as public. MIDL requires that you explicitly apply the public attribute to those typedefs that you want public.
If you import more than one type library, and if these libraries contain duplicate references, MKTYPLIB resolves this by using the first reference that it finds. MIDL will use the last reference that it finds. For example, given the following ODL syntax, library C will use the FOO typedef from library A if you compile with MKTYPLIB, and the FOO typedef from library B if you compile with MIDL:
[...]library A
{
typedef struct tagFOO
{...}FOO
}
[...]library B
{
typedef struct tagFOO
{...} FOO
}
[...]library C
{
importlib (A.TLB)
importlib (B.TLB)
typedef struct tagBAR
{FOO y;}BAR
}
The appropriate workaround for this is to qualify each such reference with the correct import library name, like this:
typedef struct tagBAR
{A.FOO y;}BAR
MIDL recognizes the C-language void data type and does not recognize the OLE Automation VOID data type. If you have an ODL file that uses VOID, place this definition at the top of the file:
#define VOID void
MIDL requires that values expressed in exponential notation be contained within quotation marks. For example, "-2.5E+3".
Normally MIDL does not consider the LCID when parsing files. To force this behavior for a value, or if you need to use locale-specific notation when defining a constant, enclose the value or constant in quotation marks.
/mktyplib203, /iid, Marshaling OLE Data Types