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


Работа с #defines в файлах IDL

На этой странице описывается, почему символы, определенные с помощью #define , исчезают из созданных компилятором MIDL H файлов и что с этим можно сделать. Это объяснение относится к любым файлам, обрабатываемым MIDL, например файлам *.idl, *.acf, *.h.

Исчезновение символов #define является результатом того, что MIDL делегирует предварительную обработку входных файлов препроцессору. По умолчанию препроцессор является препроцессором C/C++ из среды сборки. После предварительной обработки входной поток, получаемый MIDL, имеет только #line директив препроцессора. В частности, препроцессор отменяет все определения макросов во входных файлах, поэтому MIDL не может обнаружить их присутствие. Следовательно, когда MIDL реплицирует определения типов из входного файла в созданный H-файл, #defines не реплицируются. Поэтому не используйте #defines непосредственно в IDL-файлах, если они будут использоваться позже из созданного H-файла.

Рекомендуется использовать следующие четыре обходных решения.

  • Используйте спецификацию объявления const .
  • Используйте отдельные файлы заголовков, которые импортируются или включены в IDL-файл, а затем включены в исходный код C.
  • Используйте константы перечисления в IDL-файле.
  • Используйте cpp_quote для воспроизведения #define в созданном файле заголовка.

Константы манифеста можно воспроизвести с помощью синтаксиса объявления констант IDL. Обратите внимание, что const в объявлении константы IDL отличается от семантики const C/C++ и просто представляет именованную константу для компиляции IDL. Пример:

const short ARRSIZE = 10

В этом примере указывается, что ARRSIZE является константой со значением 10. Именованные константы можно использовать в деклараторах массива IDL и в других местах, где программист на языке C будет использовать определения манифеста. Кроме того, этот синтаксис приводит к созданию следующей строки в файле заголовка:

#define ARRSIZE 10

Другой способ обработки инструкций **#**define — упаковать их в отдельный файл заголовка либо в файл, посвященный операторам **#*define, либо в файл, содержащий только определения типов. Файл, содержащий только директивы препроцессора, может быть безопасно включен как в IDL-файл, так и в исходные файлы C. Хотя директивы не будут доступны в файле заголовка, созданном компилятором MIDL, программа C-source может включать отдельный файл заголовка. Аналогичным образом из IDL-файла можно импортировать файл заголовка с операторами **#**define и определениями обычных типов. Этот подход инкапсулирует операторы **#**define и typedef, используя их в H-файле, чтобы символы **#**define не использовались в импортируемом IDL-файле напрямую. Импорт заголовка или IDL-файла в другой IDL-файл предотвращает репликацию операторов typedef в H-файл, созданный MIDL (что в отличие от **#***include операторов). Такой подход позволяет безопасно ссылаться на исходный файл заголовка из кода C вместе с созданным H-файлом без проблем с повторяющимися определениями.

Также эффективно использовать константы перечисления в IDL-файле. Эти константы можно использовать в константных выражениях в IDL, например в деклараторах массива. Константы перечисления не удаляются на ранних этапах компиляции MIDL препроцессором C-компилятора, поэтому константы перечисления доступны в файле заголовка, созданном компилятором MIDL. Рассмотрим следующий оператор.

typedef enum midlworkaround { MAXSTRINGCOUNT = 300 };

Эта инструкция не будет удалена во время компиляции MIDL препроцессором C, а определение типа будет реплицировано в созданный H-файл. Константа MAXSTRINGCOUNT доступна для программ C-source, которые включают файл заголовка, созданный компилятором MIDL.

Наконец, директиву cpp_quote MIDL можно использовать для записи произвольной строки непосредственно в созданный H-файл. Например, чтобы получить константу манифеста, используемую ранее на этой странице с cpp_quote, можно использовать следующую инструкцию:

cpp_quote ("#define ARRSIZE 10")

Эта инструкция приводит к созданию следующей строки в файле заголовка:

#define ARRSIZE 10