Différences entre MIDL et MkTypLib
Notes
L’outil Mktyplib.exe est obsolète. Utilisez le compilateur MIDL à la place.
Il existe quelques domaines clés dans lesquels le compilateur MIDL diffère de MkTypLib. La plupart de ces différences se produisent parce que MIDL est plus orienté vers la syntaxe C que MkTypLib.
En général, vous souhaiterez utiliser la syntaxe MIDL dans vos fichiers IDL. Toutefois, si vous devez compiler un fichier ODL existant ou maintenir la compatibilité avec MkTypLib, utilisez l’option du compilateur MIDL /mktyplib203 pour forcer MIDL à se comporter comme Mkktyplib.exe, version 2.03. (Il s’agit de la dernière version de l’outil MkTypLib.) Plus précisément, l’option /mktyplib203 résout ces différences :
Syntaxe typedef pour les types de données complexes
Dans MkTypLib, les deux définitions suivantes génèrent un TKIND_RECORD pour « this_struct » dans la bibliothèque de types. La balise « struct_tag » est facultative et, si elle est utilisée, n’apparaît pas dans la bibliothèque de types.
typedef struct struct_tag { ... } this_struct; typedef struct { ... } that_struct;
Si une balise facultative est manquante, MIDL la génère, en ajoutant une balise à la définition fournie par l’utilisateur. Étant donné que la première définition a une balise, MIDL génère un TKIND_RECORD pour « this_struct » et un TKIND_ALIAS pour « this_struct » (définissant « this_struct » comme alias pour « struct_tag »). Étant donné que la balise est manquante dans la deuxième définition, MIDL génère un TKIND_RECORD pour un nom désactivé, interne à MIDL, qui n’est pas significatif pour l’utilisateur et un TKIND_ALIAS pour « that_struct ».
Cela a des implications potentielles pour les navigateurs de bibliothèque de types qui affichent simplement le nom d’un enregistrement dans leur interface utilisateur. Si vous vous attendez à ce qu’un TKIND_RECORD ait un vrai nom, des noms méconnaissables peuvent apparaître dans l’interface utilisateur. Ce comportement s’applique également aux définitions d’union et d’énumération , le compilateur MIDL générant des TKIND_UNIONs et des TKIND_ENUMs, respectivement.
MIDL autorise également les définitions de struct, d’union et d’énumération de style C. Par exemple, la définition suivante est légale dans MIDL :
struct my_struct { ... }; typedef struct my_struct your_struct;
types de données Boolean
Dans MkTypLib, le type de base booléen et le type de données MkTypLib BOOL correspondent à VT_BOOL, qui correspond à VARIANT_BOOL et qui est défini comme un court. Dans MIDL, le type de base booléen équivaut à VT_UI1, qui est défini comme un caractère non signé, et le type de données BOOL est défini comme long. Cela entraîne des difficultés si vous combinez la syntaxe IDL et la syntaxe ODL dans le même fichier tout en essayant de maintenir la compatibilité avec MkTypLib. Étant donné que les types de données sont de tailles différentes, le code de marshaling ne correspond pas à ce qui est décrit dans les informations de type. Si vous souhaitez une VT_BOOL dans votre bibliothèque de types, vous devez utiliser le type de données VARIANT_BOOL.
Définitions GUID dans les fichiers d’en-tête
Dans MkTypLib, les GUID sont définis dans le fichier d’en-tête avec une macro qui peut être compilée de manière conditionnelle pour générer une prédéfinition GUID ou un GUID instancié. MIDL place normalement les prédéfinissements GUID dans ses fichiers d’en-tête générés et les instanciations GUID uniquement dans le fichier généré par le commutateur /iid .
Les différences de comportement suivantes ne peuvent pas être résolues à l’aide du commutateur /mktyplib203 :
Respect de la casse
MIDL respecte la casse, OLE Automation ne l’est pas.
Étendue des symboles dans une déclaration enum
Dans MkTypLib, l’étendue des symboles dans un enum est locale. Dans MIDL, l’étendue des symboles dans un enum est globale, comme c’est le cas en C. Par exemple, le code suivant est compilé dans MkTypLib, mais génère une erreur de nom en double dans MIDL :
typedef struct { ... } a; enum {a=1, b=2, c=3};
Étendue de l’attribut public
Si vous appliquez l’attribut public à un bloc d’interface, MkTypLib traite chaque typedef à l’intérieur de ce bloc d’interface comme public. MIDL exige que vous appliquiez explicitement l’attribut public aux typesdefs que vous souhaitez public.
Ordre de recherche Importlib
Si vous importez plusieurs bibliothèques de types et que ces bibliothèques contiennent des références en double, MkTypLib résout ce problème à l’aide de la première référence qu’il trouve. MIDL utilise la dernière référence qu’il trouve. Par exemple, avec la syntaxe ODL suivante, la bibliothèque C utilisera le typedef MOO de la bibliothèque A si vous compilez avec MkTypLib, et le typedef MOO à partir de la bibliothèque B si vous compilez avec 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 }
La solution de contournement appropriée consiste à qualifier chaque référence de ce type avec le nom de bibliothèque d’importation correct, comme suit :
typedef struct tagBAA {A.MOO y;}BAA
Type de données VOID non reconnu
MIDL reconnaît le type de données void en langage C et ne reconnaît pas le type de données OLE Automation VOID. Si vous avez un fichier ODL qui utilise VOID, placez cette définition en haut du fichier :
#define VOID void '''
Notation exponentielle
MIDL exige que les valeurs exprimées en notation exponentielle soient contenues entre guillemets. Par exemple, « -2.5E+3 »
Valeurs et constantes LCID
Normalement, MIDL ne prend pas en compte le LCID lors de l’analyse des fichiers. Pour forcer ce comportement pour une valeur, ou si vous devez utiliser une notation spécifique aux paramètres régionaux lors de la définition d’une constante, placez la valeur ou la constante entre guillemets.
Pour plus d’informations, consultez /mktyplib203, /iid et Marshaling OLE Data Types.