Compartilhar via


Diferenças entre MIDL e MkTypLib

Observação

A ferramenta Mktyplib.exe está obsoleta. Em vez disso, use o compilador MIDL.

 

Há algumas áreas-chave em que o compilador MIDL difere de MkTypLib. A maioria dessas diferenças surge porque MIDL é orientada mais para a sintaxe C do que MkTypLib.

Em geral, você desejará usar a sintaxe MIDL em seus arquivos IDL. No entanto, se você precisar compilar um arquivo ODL existente ou manter a compatibilidade com MkTypLib, use a opção do compilador MIDL /mktyplib203 para forçar MIDL a se comportar como Mkktyplib.exe, versão 2.03. (Esta é a última versão da ferramenta MkTypLib.) Especificamente, a opção /mktyplib203 resolve estas diferenças:

  • sintaxe typedef para tipos de dados complexos

    No MkTypLib, ambas as definições a seguir geram uma TKIND_RECORD para "this_struct" na biblioteca de tipos. A marca "struct_tag" é opcional e, se usada, não aparecerá na biblioteca de tipos.

    typedef struct struct_tag { ... } this_struct;
    typedef struct { ... } that_struct;
    

    Se uma marca opcional estiver ausente, MIDL a gerará, adicionando efetivamente uma marca à definição fornecida pelo usuário. Como a primeira definição tem uma marca, MIDL gerará um TKIND_RECORD para "this_struct" e um TKIND_ALIAS para "this_struct" (definindo "this_struct" como um alias para "struct_tag"). Como a marca está ausente na segunda definição, MIDL gerará uma TKIND_RECORD para um nome mutilado, interno para MIDL, que não é significativo para o usuário e um TKIND_ALIAS para "that_struct".

    Isso tem possíveis implicações para navegadores de biblioteca de tipos que simplesmente mostram o nome de um registro em sua interface do usuário. Se você espera que um TKIND_RECORD tenha um nome real, nomes irreconhecíveis podem aparecer na interface do usuário. Esse comportamento também se aplica às definições de união e enumeração , com o compilador MIDL gerando TKIND_UNIONs e TKIND_ENUMs, respectivamente.

    O MIDL também permite definições de struct, união e enumeração no estilo C. Por exemplo, a seguinte definição é legal em MIDL:

    struct my_struct { ... };
    typedef struct my_struct your_struct;
    
  • Tipos de dados boolianos

    No MkTypLib, o tipo base booliano e o tipo de dados MkTypLib BOOL equivalem a VT_BOOL, que mapeia para VARIANT_BOOL e que é definido como um curto. Em MIDL, o tipo base booliano é equivalente a VT_UI1, que é definido como um caractere sem sinal, e o tipo de dados BOOL é definido como um long. Isso leva a dificuldades se você misturar sintaxe de IDL e sintaxe ODL no mesmo arquivo enquanto ainda tenta manter a compatibilidade com MkTypLib. Como os tipos de dados são tamanhos diferentes, o código de marshaling não corresponderá ao descrito nas informações de tipo. Se você quiser um VT_BOOL em sua biblioteca de tipos, deverá usar o tipo de dados VARIANT_BOOL.

  • Definições de GUID em arquivos de cabeçalho

    No MkTypLib, os GUIDs são definidos no arquivo de cabeçalho com uma macro que pode ser compilada condicionalmente para gerar uma predefinição guid ou um GUID instanciado. O MIDL normalmente coloca predefinições guid em seus arquivos de cabeçalho gerados e instanciações guid somente no arquivo gerado pela opção /iid .

As seguintes diferenças de comportamento não podem ser resolvidas usando a opção /mktyplib203 :

  • Diferenciar maiúsculas de minúsculas

    MIDL diferencia maiúsculas de minúsculas, a Automação OLE não é.

  • Escopo dos símbolos em uma declaração de enumeração

    No MkTypLib, o escopo dos símbolos em uma enumeração é local. Em MIDL, o escopo dos símbolos em uma enumeração é global, como está em C. Por exemplo, o código a seguir será compilado em MkTypLib, mas gerará um erro de nome duplicado em MIDL:

    typedef struct { ... } a;
    enum {a=1, b=2, c=3};
    
  • Escopo do atributo público

    Se você aplicar o atributo público a um bloco de interface, MkTypLib tratará cada typedef dentro desse bloco de interface como público. O MIDL exige que você aplique explicitamente o atributo público a esses typedefs que você deseja que sejam públicos.

  • Ordem de pesquisa importlib

    Se você importar mais de uma biblioteca de tipos e essas bibliotecas contiverem referências duplicadas, MkTypLib resolverá isso usando a primeira referência encontrada. MIDL usará a última referência encontrada. Por exemplo, dada a seguinte sintaxe ODL, a biblioteca C usará o typedef MOO da biblioteca A se você compilar com MkTypLib e o typedef MOO da biblioteca B se você compilar com 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
    }
    

    A solução alternativa apropriada para isso é qualificar cada referência desse tipo com o nome correto da biblioteca de importação, desta forma:

    typedef struct tagBAA
        {A.MOO y;}BAA
    
  • Tipo de dados VOID não reconhecido

    O MIDL reconhece o tipo de dados void da linguagem C e não reconhece o tipo de dados VOID da Automação OLE. Se você tiver um arquivo ODL que usa VOID, coloque essa definição na parte superior do arquivo:

#define void void '''

  • Notação exponencial

    MIDL exige que os valores expressos na notação exponencial estejam contidos entre aspas. Por exemplo, "-2.5E+3"

  • Valores e constantes LCID

    Normalmente, MIDL não considera o LCID ao analisar arquivos. Para forçar esse comportamento para um valor ou se você precisar usar notação específica da localidade ao definir uma constante, coloque o valor ou a constante entre aspas.

Para obter mais informações, consulte /mktyplib203, /iid e Marshaling OLE Data Types.