Поделиться через


Различия между 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 оба следующих определения создают TKIND_RECORD для this_struct в библиотеке типов. Тег "struct_tag" является необязательным и, если он используется, не отображается в библиотеке типов.

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

    Если необязательный тег отсутствует, MIDL создаст его, фактически добавив тег в определение, предоставленное пользователем. Так как первое определение содержит тег, MIDL создает TKIND_RECORD для "this_struct" и TKIND_ALIAS для "this_struct" (определяя "this_struct" в качестве псевдонима для "struct_tag"). Так как тег отсутствует во втором определении, MIDL создаст TKIND_RECORD для искаженного имени, внутреннее для MIDL, которое не имеет смысла для пользователя и TKIND_ALIAS для "that_struct".

    Это может повлиять на браузеры библиотек типов, которые просто отображают имя записи в пользовательском интерфейсе. Если вы ожидаете, что TKIND_RECORD будет иметь реальное имя, в пользовательском интерфейсе могут отображаться неузнаваемые имена. Это поведение также применяется к определениямобъединения и перечисления, при этом компилятор MIDL создает TKIND_UNIONs и TKIND_ENUMs соответственно.

    MIDL также позволяет использовать определения структуры, объединения и перечисления в стиле C. Например, следующее определение является допустимым в MIDL:

    struct my_struct { ... };
    typedef struct my_struct your_struct;
    
  • Логические типы данных

    В MkTypLib логический базовый тип и тип данных MkTypLib BOOL приравниваются к VT_BOOL, который сопоставляется с VARIANT_BOOL и определяется как короткий. В MIDL логический базовый тип эквивалентен VT_UI1, который определяется как символ без знака, а тип данных BOOL определяется как long. Это приводит к трудностям, если вы смешиваете синтаксис IDL и синтаксис ODL в одном файле, но при этом пытаетесь поддерживать совместимость с MkTypLib. Так как типы данных имеют разные размеры, код маршалинга не будет соответствовать описанному в сведениях о типе. Если требуется VT_BOOL в библиотеке типов, следует использовать тип данных VARIANT_BOOL.

  • Определения GUID в файлах заголовков

    В MkTypLib идентификаторы GUID определяются в файле заголовка с помощью макроса, который можно условно скомпилировать для создания предварительного идентификатора GUID или экземпляра GUID. MIDL обычно помещает предопределения GUID в созданные файлы заголовков, а экземпляры GUID — только в файл, созданный параметром /iid .

Следующие различия в поведении не могут быть устранены с помощью параметра /mktyplib203 :

  • Чувствительность к регистру

    В MIDL учитывается регистр, ole Automation — нет.

  • Область символов в объявлении перечисления

    В MkTypLib область символов в перечислении является локальным. В MIDL область символов в перечислении является глобальным, как и в C. Например, следующий код будет компилироваться в MkTypLib, но создаст ошибку повторяющегося имени в MIDL:

    typedef struct { ... } a;
    enum {a=1, b=2, c=3};
    
  • Область действия открытого атрибута

    При применении атрибута public к блоку интерфейса MkTypLib обрабатывает каждое определение типа внутри этого блока интерфейса как открытый. MIDL требует явного применения атрибута public к тем typedefs, которые требуется сделать общедоступными.

  • Порядок поиска Importlib

    Если вы импортируете несколько библиотек типов и если эти библиотеки содержат повторяющиеся ссылки, MkTypLib разрешает эту проблему с помощью первой найденной ссылки. MIDL будет использовать последнюю найденную ссылку. Например, учитывая следующий синтаксис ODL, библиотека C будет использовать определение типа MOO из библиотеки A при компиляции с помощью MkTypLib, а определение типа MOO из библиотеки B — при компиляции с помощью 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 распознает тип данных void языка C и не распознает тип данных OLE Automation VOID. Если у вас есть ODL-файл, использующий VOID, поместите это определение в начало файла:

#define VOID void '''

  • Экспоненциальная нотация

    MIDL требует, чтобы значения, выраженные в экспоненциальной нотации, содержались в кавычках. Например, "-2.5E+3"

  • Значения и константы LCID

    Как правило, MIDL не учитывает LCID при анализе файлов. Чтобы принудительно применить это поведение для значения или если при определении константы необходимо использовать нотацию, относящееся к языковому стандарту, заключите значение или константу в кавычки.

Дополнительные сведения см. в разделах /mktyplib203, /iid и Маршалинг типов данных OLE.