Lidando com #defines em arquivos IDL

Esta página descreve por que os símbolos definidos com um #define desaparecem dos arquivos H gerados pelo compilador MIDL e o que pode ser feito sobre ele. Essa explicação se aplica a todos os arquivos processados pelo MIDL, como arquivos *.idl, *.acf, *.h.

O desaparecimento de símbolos de #define é resultado da delegação midl do pré-processamento de arquivos de entrada para um pré-processador. Por padrão, o pré-processador é um pré-processador C/C++ do ambiente de build. Após o pré-processamento, o fluxo de entrada que MIDL recebe tem apenas #line diretivas de pré-processador. Em particular, o pré-processador cancela o registro de todas as definições de macro em arquivos de entrada e, portanto, MIDL não pode detectar sua presença. Consequentemente, quando MIDL replica definições de tipo de um arquivo de entrada para o arquivo H gerado, os #defines não são replicados. Portanto, não use #defines diretamente em arquivos IDL se eles forem usados posteriormente do arquivo H gerado.

As quatro soluções alternativas a seguir são recomendadas:

  • Use a especificação de declaração const .
  • Use arquivos de cabeçalho separados que são importados ou incluídos no arquivo IDL e posteriormente incluídos no código-fonte C.
  • Use constantes de enumeração no arquivo IDL.
  • Use cpp_quote para reproduzir #define no arquivo de cabeçalho gerado.

Você pode reproduzir constantes de manifesto usando a sintaxe de declaração constante IDL. Observe que o const na declaração constante de IDL é diferente da semântica de const C/C++ e simplesmente introduz uma constante nomeada para uma compilação IDL. Por exemplo:

const short ARRSIZE = 10

Este exemplo especifica que ARRSIZE é uma constante com um valor de 10. Constantes nomeadas podem ser usadas em declaradores de matriz IDL e em outros locais onde um programador C usaria um manifesto definido. Além disso, essa sintaxe resulta na seguinte linha que está sendo gerada no arquivo de cabeçalho:

#define ARRSIZE 10

Outra maneira de manipular instruções **#**definem é empacotá-las em um arquivo de cabeçalho separado, seja em um arquivo dedicado a instruções **#**definir ou em um arquivo que contenha apenas definições de tipo. Um arquivo que contém apenas diretivas de pré-processador pode ser incluído com segurança tanto pelo arquivo IDL quanto pelos arquivos de origem C. Embora as diretivas não estejam disponíveis no arquivo de cabeçalho gerado pelo compilador MIDL, o programa de origem C pode incluir o arquivo de cabeçalho separado. De forma semelhante, um arquivo de cabeçalho com instruções **#**definem instruções e definições de tipo regular pode ser importado do arquivo IDL. Essa abordagem encapsula as instruções **#**definir e typedef usando-as em um arquivo H de modo que os símbolos **#**definem não sejam usados diretamente no arquivo IDL de importação. Importar um cabeçalho ou arquivo IDL para outro arquivo IDL impede que as instruções typedef sejam replicadas para o arquivo H gerado por MIDL (que contrasta com instruções **#**include). Essa abordagem permite que o arquivo de cabeçalho original seja referenciado com segurança do código C ao longo do arquivo H gerado sem ter um problema com definições duplicadas.

O uso de constantes de enumeração no arquivo IDL também é eficaz. Essas constantes podem ser usadas em expressões constantes no IDL, por exemplo, em declaradores de matriz. As constantes de enumeração não são removidas durante as fases iniciais da compilação MIDL pelo pré-processador do compilador C, portanto, as constantes de enumeração estão disponíveis no arquivo de cabeçalho gerado pelo compilador MIDL. Considere o seguinte instrução:

typedef enum midlworkaround { MAXSTRINGCOUNT = 300 };

Essa instrução não será removida durante a compilação MIDL pelo pré-processador C e o typedef será replicado para o arquivo H gerado. O MAXSTRINGCOUNT constante está disponível para programas de origem C que incluem o arquivo de cabeçalho gerado pelo compilador MIDL.

Por fim, a diretiva cpp_quote de MIDL pode ser usada para gravar uma cadeia de caracteres arbitrária diretamente no arquivo H gerado. Por exemplo, para obter a constante de manifesto usada anteriormente nesta página com cpp_quote, a seguinte instrução pode ser usada:

cpp_quote ("#define ARRSIZE 10")

Essa instrução resulta na seguinte linha que está sendo gerada no arquivo de cabeçalho:

#define ARRSIZE 10