ID do artigo: 154093 - Última revisão: terça-feira, 21 de novembro de 2006 - Revisão: 3.3

Como chamar código de 32 bits do código de 16 bits no Windows 95, Windows 98 ou Windows Millennium Edition

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.

Nesta página

Expandir tudo | Recolher tudo

Sumário

Geralmente é desejável para aplicativos Win16 de porta e DLLs Win32 um pouco em um tempo em vez de todas ao mesmo tempo. Por exemplo, convém porta DLLs de 16 bits para Win32, mas ainda poderá chamá-los do código de 16 bits. Este artigo descreve o mecanismo pelo qual DLLs de 16 bits podem chamar DLLs de 32 bits. O mecanismo é chamado de uma conversão e o método implementado no Microsoft Windows 95, Windows 98 ou Windows Millennium Edition (Me) é chamado de uma conversão simples.

As três etapas principais escrever o código de conversão são:
  1. Criando o script de conversão.
  2. Criando a DLL de 16 bits.
  3. Criando a DLL de 32 bits.

Mais Informações

Uma conversão simples consiste em uma DLL de 32 bits que funcionam juntos e 16 bits. A Chama de aplicativo Win16 a DLL de 16 bits e a DLL de 16 bits chama uma função exportada na DLL de 32 bits. Quando a função na DLL de 32 bits retorna, ele retorna para a DLL de 16 bits, que por sua vez retorna volta para o aplicativo Win16. Trabalho de DLLs 16 e 32 bits, chamando o Windows 95, Windows 98 ou kernels me 16 bits do Windows e de 32 bits para lidar com todos os os detalhes de baixo nível necessários para fazer a transição do código de 16 bits para 32 bits e de volta.

Criar uma nova conversão simples envolve criar um script de conversão (.THK arquivo). Esse script é compilado com o compilador de conversão em um arquivo de linguagem assembly que é montado duas vezes; uma vez a cada um dos dois sinalizadores:-DIS_16 e - DIS_32. O resultado é um módulo de objeto de 32 bits e 16 bits. Esses módulos de objeto são vinculados às DLLs de 32 bits e 16 bits respectivamente. O diagrama a seguir resume os arquivos envolvidos na criação de DLLs:
                       +------------+
                       | 16to32.THK |
                       +------------+
                             |
                       +------------+
                       | 16to32.ASM |
                       +------------+
                        /          \ 
               -DIS_16 /            \ -DIS_32
                      /              \ 
                 +-----------+ +-----------+
                 | 16THK.OBJ | | 32THK.OBJ |
                 +-----------+ +-----------+
                       /                  \ 
      +-------+    +-------+             +-------+
      | APP16 | -> | DLL16 | -- THUNK -- | DLL32 |
      +-------+    +-------+             +-------+
				

Ferramentas necessárias para criar Thunks simples

  1. Microsoft Visual C++ 1.5 x (compilador de 16 bits) para o lado 16 bits da conversão. O lado de 16 bits da conversão é uma DLL de 16 bits.
  2. Microsoft Visual C++ 2.x ou superior (compilador de 32 bits) para o lado de 32 bits da conversão. O lado de 32 bits da conversão é uma DLL de 32 bits.
  3. Compilador de conversão (thunk.exe) do Microsoft Win32 SDK para compilar scripts de conversão.
  4. Macro de Microsoft Assembler (MASM) versão 6.1 ou superior para montar a saída de linguagem assembly do compilador de conversão.
  5. RC.EXE 16 bits do diretório BINW16 do Microsoft Win32 SDK para marcar a DLL de conversão de 16 bits como versão 4.0.

Criar o Script Thunk

Você precisará criar um script que será usado pelo compilador conversão para criar uma conversão. Um script de conversão é um arquivo de texto que contém definições de tipo, protótipos de função das funções que você deseja chamar via thunks e uma especificação da direção dos parâmetros para cada função. Por exemplo, algumas funções requerem parâmetros de entrada e saídos enquanto outros podem exigir somente parâmetros de entrada. Conversão scripts usam sintaxe especial para descrever se parâmetros são entrados, saída, ou entrada e saída.

Um script de conversão para 16-> 32 thunks começa com a instrução a seguir:
enablemapdirect1632 = true;
Por padrão, a DLL de 32 bits é carregada somente quando uma conversão para ele é executado pela primeira vez. Como essa ligação tardia é usada, o código de 16 bits deve depender não qualquer ação realizada pela inicialização da DLL de 32 bits. Porque a DLL de 32 bits será carregado somente quando o primeiro thunk para ele é executado, problemas ao carregar a DLL de 32 bits não serão detectados quando a DLL de 16 bits for carregado pela primeira vez. Para desativar a ligação tardia da DLL de 32 bits, adicione a seguinte linha no script conversão:
preload32 = true;
O compilador de conversão espera que o lado de 16 bits da conversão é declarado como __pascal __far e que o lado de 32 bits é __stdcall. (A declaração WINAPI cuida desse em ambos os lados.) O __cdecl e __fastcall convenções de chamada não são suportados pelo compilador conversão. No entanto, observe que o compilador de conversão não aceita, na verdade, as palavras-chave __far, __pascal ou __stdcall; eles são considerados.

O script de conversão a seguir descreve uma função sem parâmetros:
   enablemapdirect1632 = true;

   void MyThunk32()
   {
   }
				
a declaração equivalente seria:
   C   language:    void WINAPI MyThunk32(void);
   C++ Language:    extern "C" void WINAPI MyThunk32();
				
a função no script de exemplo a seguir usa dois parâmetros e retorna um valor. O segundo parâmetro é um parâmetro de saída e contém um ponteiro que é passado de volta para a DLL de 16 bits:
   enablemapdirect1632 = true;

   typedef int   BOOL;
   typedef char *LPSTR;

   BOOL MyThunk32(LPSTR lpstrInput, LPSTR lpstrOutput)
   {
      lpstrInput  = input;   // optional; input is default
      lpstrOutput = output;
   }
				
a instrução "lpstrOutput = saída" informa o compilador de conversão que a função de 32 bits retornará um endereço que precisa ser convertido de um endereço de 32 bits linear para um ponteiro de seletor: deslocamento.

O seguinte script de conversão usa tipos de parâmetro mais complexos, como estruturas. Este exemplo também mostra como especificar parâmetros de entrada e saídos:
   enablemapdirect1632 = true;

   typedef unsigned int UINT;
   typedef char *LPSTR;

   typedef struct _POINT {
      UINT x;
      UINT y;
   }POINT, *LPPOINT;

   typedef struct _CIRCLE {
      POINT center;
      UINT  radius;
   }CIRCLE, *LPCIRCLE;

   void MyThunk32( LPCIRCLE lpCircleInOut)
   {
      lpCircleInOut = inout;
   }
				
a instrução "lpCircleInOut = inout" informa o compilador de conversão que esse ponteiro será a ser usado para entrada e saída. Isso faz com que o compilador de conversão converter lpCircleInOut de um ponteiro de 16 bits far (seletor: deslocamento) em um endereço de 32 bits linear quando a função é chamada e, em seguida, de volta para um ponteiro de mais de 16 bits quando a função retorna. A conversão é manipulada pela conversão criado pelo compilador conversão.

Usando o compilador Thunk

O uso do compilador de conversão é da seguinte maneira:
Thunk.exe/opções <outputfile> <inputfile> -o
A linha a seguir mostra como compilar uma 16-> 32 script de conversão. Essa linha tem um script chamado 16to32.thk e produz um arquivo de linguagem assembly denominado 16to32.asm:
conversão -t thk 16to32.thk -o 16to32.asm
O "-t thk" opção informa o compilador de conversão para as funções de conversão no arquivo de linguagem assembly com "thk_" prefixo. Esse prefixo é usado ao vincular vários scripts de conversão em um par de DLLs e é útil para criar um par de DLLs que contêm ambas 16-> 32-> 16 thunks e 32.

Criando a DLL de 16 bits

  1. A DLL de 16 bits deve exportar uma função chamada "DllEntryPoint". Esta função deve fazer uma chamada para uma função criada pelo compilador conversão chamado thk_ThunkConnect16 ("thk" é o prefixo do comutador conversão compilador -t) toda vez que é chamado de DllEntryPoint:
       // prototype for function in .OBJ from the thunk script
       BOOL WINAPI __export thk_ThunkConnect16(LPSTR lpDll16,
                                               LPSTR lpDll32,
                                               WORD  hInst,
                                               DWORD dwReason);
    
        BOOL WINAPI thk_thunkConnect16(LPSTR, LPSTR, WORD, DWORD);
    
        BOOL WINAPI __export DllEntryPoint(DWORD dwReason,
                                           WORD  hInst,
                                           WORD  wDS,
                                           WORD  wHeapSize,
                                           DWORD dwReserved1,
                                           WORD  wReserved 2)
        {
           if (!thk_ThunkConnect16("DLL16.DLL", "DLL32.DLL",
                                   hInst, dwReason))
              return FALSE;
    
            return TRUE;
        }
    						
  2. Inclua as seguintes linhas na seção IMPORTAÇÕES do arquivo de definição (DEF) módulo para a DLL de 16 bits:
       C16ThkSL01      = KERNEL.631
       ThunkConnect16  = KERNEL.651
    						
  3. Inclua as seguintes linhas na seção EXPORTS do arquivo de definição (.def) módulo para a DLL de 16 bits. THK_THUNKDATA16 é definido no arquivo do objeto montado da saída do compilador de conversão. Ambos esses símbolos deve ter a palavra-chave RESIDENTNAME, mas pode ter qualquer número ordinal:
       THK_THUNKDATA16 @1  RESIDENTNAME
       DllEntryPoint   @2  RESIDENTNAME
    						
  4. Adicione as funções de conversão que o aplicativo Win16 chamará à instrução EXPORTS do arquivo de definição (DEF) de módulo da DLL de 16 bits. Certifique-se eles são declarados e definidos como __pascal __far __export (ou WINAPI __export). Se a DLL está escrita em C++, certifique-se de declará-los como extern "C".
  5. Compilar a conversão da seguinte maneira (se ainda não compilado):
       thunk -t thk 16to32.thk -o 16to32.asm
    						
  6. Em seguida, monte o arquivo de linguagem assembly gerado pelo compilador conversão como um módulo de objeto de 16 bits. A linha a seguir mostra um exemplo:
    ml /DIS_16 /c /W3 /nologo /Fo thk16.obj 16to32.asm
    						
  7. Vincule este módulo de objeto como parte da DLL de 16 bits.
  8. Marcar a DLL de 16 bits como versão 4.0. Para fazer isso, use o compilador de recurso (RC.EXE). A linha a seguir mostra a sintaxe:
    rc 40 º < arquivo DLL >
    Esta opção de 40 º está disponível no compilador de recurso é fornecido com o Win32 SDK.

    Observação : Certifique-se usar RC.EXE no diretório BINW16 para que a DLL é marcada com versão 4.0. RC.EXE que acompanha as versões de 16 bits do Microsoft Visual C++ não marcará a DLL como versão 4.0.

Criando a DLL de 32 bits

  1. No DllMain de sua DLL de 32 bits, você deve fazer uma chamada para uma função criada pelo compilador conversão chamado thk_ThunkConnect32 sempre DllMain é chamado, como mostrado aqui ("thk" é o prefixo do compilador do conversão - t opção):
       // prototype for function in .OBJ from the thunk script
       BOOL WINAPI thk_ThunkConnect32 (LPSTR     lpDll16,
                                       LPTSR     lpDll32,
                                       HINSTANCE hDllInst,
                                       DWORD     dwReason);
    
       BOOL WINAPI DllMain (HINSTANCE hDLLInst,
                            DWORD     dwReason,
                            LPVOID    lpvReserved)
       {
          if (!thk_ThunkConnect32("DLL16.DLL",
                                  "DLL32.DLL",
                                  hDLLInst,
                                  dwReason))
          {
             return FALSE;
          }
          switch (dwReason)
          {
             case DLL_PROCESS_ATTACH:
                break;
    
             case DLL_PROCESS_DETACH:
                break;
    
             case DLL_THREAD_ATTACH:
                break;
    
             case DLL_THREAD_DETACH:
                break;
          }
          return TRUE;
       }
    						
  2. Inclua as seguintes linhas na seção EXPORTS do arquivo de definição (.def) módulo para a DLL de 32 bits:
    thk_ThunkData32
    						
  3. Exporte as funções para o qual você é conversão. Você pode usar o arquivo de definição (DEF) de módulo da DLL de 32 bits ou a palavra-chave __declspec(dllexport). Certifique-se eles são declarados e definidos como __stdcall. Se a DLL de 32 bits está escrita em C++, certifique-se de declará-los como extern "C". Essas funções são chamadas por lado da conversão 16 bits.
  4. Compilar o script de conversão da seguinte maneira (se ainda não compilado):
    thunk -t thk 16to32.thk -o 16to32.asm
    						
  5. Monte o arquivo de linguagem assembly gerado pelo compilador conversão como um módulo de objeto de 32 bits. A linha a seguir mostra um exemplo:
    ml /DIS_32 /c /W3 /nologo /coff /Fo thk32.obj 16to32.asm
    						
  6. Vincule este módulo de objeto como parte da DLL de 32 bits.
  7. Vincule thunk32.lib como parte da DLL de 32 bits. Isso é a biblioteca de importação de 32 bits fornecida no SDK do Win32 que contém referências para as APIs de conversão (thunking) de 32 bits que usa o código criado pelo compilador conversão.

Referências

Para obter informações sobre como depurar thunks simples, consulte o seguinte artigo na Base de dados de Conhecimento da Microsoft:
133722  (http://support.microsoft.com/kb/133722/EN-US/ ) Como depurar Thunks simples

A informação contida neste artigo aplica-se a:
  • Interface de Programação de Aplicativos do Microsoft Win32 nas seguintes plataformas
    • Microsoft Windows 95
    • Microsoft Windows 98 Standard Edition
    • Microsoft Windows Millennium Edition
Palavras-chave: 
kbmt kbapi kbkernbase kbnetwork kbthunks KB154093 KbMtpt
Tradução automáticaTradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 154093  (http://support.microsoft.com/kb/154093/en-us/ )
Retired KB ArticleAviso de Isenção de Responsabilidade sobre Conteúdo do KB Aposentado
Este artigo trata de produtos para os quais a Microsoft não mais oferece suporte. Por esta razão, este artigo é oferecido "como está" e não será mais atualizado.