Различия между 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.