MIDL 和 MkTypLib 之间的差异
注意
Mktyplib.exe 工具已过时。 请改用 MIDL 编译器。
MIDL 编译器与 MkTypLib 不同,有几个关键领域。 之所以出现这些差异,是因为 MIDL 更面向 C 语法,而不是 MkTypLib。
通常,需要在 IDL 文件中使用 MIDL 语法。 但是,如果需要编译现有的 ODL 文件,或者保持与 MkTypLib 的兼容性,请使用 /mktyplib203 MIDL 编译器选项强制 MIDL 的行为类似于 Mkktyplib.exe版本 2.03。 (这是 MkTypLib 工具的最后一个版本。具体而言,/mktyplib203 选项解决了以下差异:
复杂数据类型的 typedef 语法
在 MkTypLib 中,以下两个定义都为类型库中的“this_struct”生成TKIND_RECORD。 标记“struct_tag”是可选的,如果使用,则不会显示在类型库中。
typedef struct struct_tag { ... } this_struct; typedef struct { ... } that_struct;
如果缺少可选标记,MIDL 将生成它,从而有效地将标记添加到用户提供的定义。 由于第一个定义具有标记,MIDL 将为“this_struct”生成TKIND_RECORD,并为“this_struct”生成TKIND_ALIAS(将“this_struct”定义为“struct_tag”的别名)。 由于第二个定义中缺少标记,MIDL 将为内部到 MIDL 的混乱名称生成TKIND_RECORD,对用户没有意义,并且为“that_struct”生成TKIND_ALIAS。
这对类型库浏览器的潜在影响,这些浏览器只是在其用户界面中显示记录的名称。 如果预期TKIND_RECORD具有实名,则无法识别的名称可能会显示在用户界面中。 此行为也适用于 联合 和 枚举 定义,MIDL 编译器分别生成TKIND_UNIONs和TKIND_ENUMs。
MIDL 还允许 C 样式 结构、联合和 枚举 定义。 例如,以下定义在 MIDL 中是合法的:
struct my_struct { ... }; typedef struct my_struct your_struct;
布尔数据类型
在 MkTypLib 中,布尔 基类型和 MkTypLib 数据类型 BOOL 等同于映射到VARIANT_BOOL的 VT_BOOL,定义为 短。 在 MIDL 中,布尔 基类型等效于VT_UI1,该类型定义为 无符号字符,BOOL 数据类型定义为 长。 如果在同一文件中混合 IDL 语法和 ODL 语法,但仍尝试保持与 MkTypLib 的兼容性,这会导致困难。 由于数据类型不同,封送处理代码与类型信息中描述的代码不匹配。 如果需要类型库中的VT_BOOL,则应使用VARIANT_BOOL数据类型。
头文件中的 GUID 定义
在 MkTypLib 中,GUID 在头文件中定义,其宏可以有条件编译以生成 GUID 预定义或实例化 GUID。 MIDL 通常将其生成的头文件和 GUID 实例化放在由 /iid 开关生成的文件中。
使用 /mktyplib203 开关无法解决以下行为差异:
区分大小写
MIDL 区分大小写,OLE 自动化不区分大小写。
枚举声明中的符号范围
在 MkTypLib 中,枚举中的符号范围是本地的。 在 MIDL 中,枚举中的符号范围是全局的,因为它在 C 中。例如,以下代码将在 MkTypLib 中编译,但在 MIDL 中生成重复的名称错误:
typedef struct { ... } a; enum {a=1, b=2, c=3};
公共属性的范围
如果将 公共 属性应用于接口块,MkTypLib 会将该接口块中的每个 typedef 视为公共。 MIDL 要求将 公共 属性显式应用于想要公开的 typedefs。
Importlib 搜索顺序
如果导入多个类型库,并且这些库包含重复引用,则 MkTypLib 会通过使用它找到的第一个引用来解决此问题。 MIDL 将使用它找到的最后一个引用。 例如,如果使用以下 ODL 语法,库 C 将使用库 A 中的 MOO typedef(如果使用 MkTypLib 进行编译)和库 B 中的 MOO typedef(如果使用 MIDL 进行编译):
[...]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 }
适当的解决方法是使用正确的导入库名称限定每个此类引用,如下所示:
typedef struct tagBAA {A.MOO y;}BAA
无法识别 VOID 数据类型
MIDL 识别 C 语言 void 数据类型,并且无法识别 OLE Automation VOID 数据类型。 如果你有使用 VOID 的 ODL 文件,请将此定义放在文件顶部:
#define VOID void “'”
指数表示法
MIDL 要求以指数表示法表示的值包含在引号内。 例如,“-2.5E+3”
LCID 值和常量
通常,MIDL 在分析文件时不考虑 LCID。 若要强制对值执行此行为,或者在定义常量时需要使用区域设置特定的表示法,请将值或常量括在引号中。
有关详细信息,请参阅 /mktyplib203、/iid和 封送 OLE 数据类型。