Artigo: 154093 - Última revisão: terça-feira, 21 de Novembro de 2006 - Revisão: 3.3

Como chamar o 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 | Reduzir tudo

Sumário

Muitas vezes é desejável a porta Win16 aplicações e dll para Win32 um pouco cada vez e não ao mesmo tempo. Por exemplo, convém porta dll de 16 bits para Win32 mas ainda conseguir chamá-los do código de 16 bits. Este artigo descreve o mecanismo pelo qual as DLL de 16 bits podem chamar dll de 32 bits. O mecanismo é designado por um thunk e o método implementado no Microsoft Windows 95, Windows 98 ou Windows Millennium Edition (Me) é designado por um thunk simples.

Os três passos principais ao escrever o código de thunk são:
  1. Criar thunk script.
  2. Criar a DLL de 16 bits.
  3. Criar a DLL de 32 bits.

Mais Informação

Uma simples thunk consiste de 16-bit e uma DLL de 32 bits que funcionam em conjunto. A Chamadas de aplicações Win16 a DLL de 16 bits e a DLL de 16 bits chama uma função exportada a DLL de 32 bits. Quando a função na DLL de 32 bits devolve, devolve novamente para a DLL de 16 bits, que por sua vez devolve novamente para a aplicação Win16. O 16-bit e 32 bits dll trabalho através do Windows 95, Windows 98 ou Windows Me 16-bit e 32 bits kernels para processar todos os detalhes de nível inferior necessários para fazer a transição do código de 16 bits para 32 bits e novamente.

Criar um novo thunk simples envolve a criação de scripts thunk (.THK ficheiro). Este script é compilado com o compilador thunk num ficheiro linguagem de assemblagem que está montado duas vezes; uma vez com cada um dos dois sinalizadores:-DIS_16 e - DIS_32. O resultado é 16-bit e um módulo de objecto de 32 bits. Estes módulos de objecto são ligados respectivamente as DLL de 16 bits e 32 bits. O diagrama seguinte resume os ficheiros envolvidos na criação as DLL:
                       +------------+
                       | 16to32.THK |
                       +------------+
                             |
                       +------------+
                       | 16to32.ASM |
                       +------------+
                        /          \ 
               -DIS_16 /            \ -DIS_32
                      /              \ 
                 +-----------+ +-----------+
                 | 16THK.OBJ | | 32THK.OBJ |
                 +-----------+ +-----------+
                       /                  \ 
      +-------+    +-------+             +-------+
      | APP16 | -> | DLL16 | -- THUNK -- | DLL32 |
      +-------+    +-------+             +-------+
				

Ferramentas necessárias para criar Thunks plano

  1. Microsoft Visual C++ 1,5 x (compilador de 16 bits) para o lado 16-bit do thunk. Lado do thunk 16-bit é uma DLL de 16-bit.
  2. Microsoft Visual C++ 2.x ou superior (compilador de 32 bits) para o lado de 32 bits do thunk. O lado de 32 bits do thunk está uma DLL de 32 bits.
  3. Thunk compilador (thunk.exe) a partir do Microsoft Win32 SDK para compilar thunk scripts.
  4. Macro de Microsoft Assembler (MASM) versão 6.1 ou superior para juntar o resultado de linguagem de assemblagem do compilador thunk.
  5. RC.EXE 16-bit do directório BINW16 do Microsoft Win32 SDK para marcar a 16 bits thunk DLL como versão 4.0.

Criar o Script Thunk

Tem de criar um script que será utilizado pelo compilador thunk para criar um thunk. Um script thunk é um ficheiro de texto que contém definições de tipo de protótipos de função das funções que deseja chamar através de thunks e uma especificação da direcção de parâmetros para cada função. Por exemplo, algumas funções requerem parâmetros de entrada e saídos, enquanto outros só poderão necessitar de parâmetros de entrada. Thunk scripts utilizam sintaxe especial para descrever se parâmetros são entrados, saída, ou entrada e saída.

Um script thunk 16-> 32 thunks começa com a seguinte instrução:
enablemapdirect1632 = VERDADEIRO;
Por predefinição, a DLL de 32 bits é carregada apenas quando um thunk a ele é executado pela primeira vez. Uma vez que este enlace tardio é utilizado, código de 16 bits tem não depender qualquer acção efectuada pela inicialização da DLL de 32 bits. Uma vez que irá carregar a DLL de 32 bits quando o primeiro thunk para executar, problemas ao carregar a DLL de 32 bits não serão detectados quando carrega pela primeira vez a DLL de 16 bits. Para desactivar o enlace tardio da DLL de 32 bits, adicione a seguinte linha no script thunk:
preload32 = VERDADEIRO;
O compilador thunk espera que lado do thunk 16 bits é declarado como __pascal __far e de que o lado de 32 bits é __stdcall. (Declaração WINAPI encarrega deste em ambos os lados.) Não são suportadas pelo compilador thunk __cdecl os __fastcall convenções de chamada. No entanto, tenha em atenção que o compilador thunk não aceita, na realidade, as palavras-chave __far, __pascal ou __stdcall; são considerados como.

O seguinte script thunk descreve uma função sem parâmetros:
   enablemapdirect1632 = true;

   void MyThunk32()
   {
   }
				
seria a declaração equivalente:
   C   language:    void WINAPI MyThunk32(void);
   C++ Language:    extern "C" void WINAPI MyThunk32();
				
a função no script de exemplo seguinte assume dois parâmetros e devolve um valor. O segundo parâmetro é um parâmetro de saída e contém um apontador que é transmitido 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" indica o compilador thunk que a função de 32 bits devolverá um endereço que necessita de ser convertida de um endereço linear de 32 bits para um ponteiro de selecção: Desvio.

O seguinte script de thunk utiliza tipos de parâmetro mais complexos, tais como estruturas. Este exemplo mostra também 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" indica o compilador de thunk este ponteiro vai ser usada para entrada e saída. Isto faz com que o compilador thunk converter lpCircleInOut de um ponteiro de 16 bits extremidade (selector: desfasamento) para um endereço linear de 32 bits quando a função é chamada e, em seguida, novamente para um ponteiro de extremidade de 16 bits quando a função devolve. A conversão é tratada pelo thunk criado pelo compilador thunk.

Utilizar o compilador Thunk

A utilização de compilador thunk é:
Thunk.exe/opções <outputfile> <inputfile> -o
A linha seguinte mostra como compilar um 16-> script thunk 32. Esta linha tem um script denominado 16to32.thk e produz um ficheiro de linguagem assembly denominado 16to32.asm:
Thunk -t thk 16to32.thk -o 16to32.asm
O "-t thk" opção informa o compilador thunk como prefixo as funções thunk do ficheiro linguagem assembly "thk_". Este prefixo é utilizado quando ligar vários thunk scripts para um par de DLLs e é útil para criar um par de DLLs que contêm ambas 16-> 32 e 32-> 16 thunks.

Criar a DLL de 16 bits

  1. A DLL de 16 bits tem de exportar uma função com o nome "DllEntryPoint". Esta função deve efectuar uma chamada para uma função criada pelo compilador thunk denominado thk_ThunkConnect16 ("thk" é o prefixo do parâmetro do thunk compilador -t) sempre que DllEntryPoint é designado por:
       // 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. Inclui as seguintes linhas na secção de ficheiro de definição (DEF) do módulo IMPORTA para a DLL de 16 bits:
       C16ThkSL01      = KERNEL.631
       ThunkConnect16  = KERNEL.651
    						
  3. Inclua as seguintes linhas na secção EXPORTS do ficheiro módulo (.def) de definição para a DLL de 16 bits. THK_THUNKDATA16 está definido no ficheiro de objecto é montado a partir dos resultados do compilador thunk. Ambos estes símbolos tem de ter a palavra-chave RESIDENTNAME, mas pode ter qualquer número ordinal:
       THK_THUNKDATA16 @1  RESIDENTNAME
       DllEntryPoint   @2  RESIDENTNAME
    						
  4. Adicione as funções thunk que irão invocar aplicações Win16 à instrução EXPORTS do ficheiro de definição (DEF) do módulo a DLL de 16 bits. Certifique-se que são declarados e definidos como __pascal __far __export (ou WINAPI __export). Se a DLL for escrita em C++, não se esqueça declará-los como bem externo "C".
  5. Compilar o thunk maneira (se ainda não compilada):
       thunk -t thk 16to32.thk -o 16to32.asm
    						
  6. Em seguida, monte o ficheiro de linguagem assembly produzido pelo compilador thunk como um módulo de objecto de 16 bits. A linha seguinte mostra um exemplo:
    ml /DIS_16 /c /W3 /nologo /Fo thk16.obj 16to32.asm
    						
  7. Ligar este módulo de objecto como parte da DLL de 16 bits.
  8. Marca a DLL de 16 bits, versão 4.0. Para o fazer, utilize o compilador de recurso (RC.EXE). A seguinte linha mostra a sintaxe:
    rc-40 < ficheiro DLL >
    Esta opção-40 está disponível no compilador de recurso fornecido com o SDK do Win32.

    Nota : Se utilizar o RC.EXE no directório BINW16 para que a DLL estiver marcada com versão 4.0. RC.EXE fornecido com versões de 16 bits do Microsoft Visual C++ não irá marcar a DLL, versão 4.0.

Criar a DLL de 32 bits

  1. DllMain da DLL de 32 bits, tem de estabelecer uma chamada para uma função criada pelo compilador thunk denominado thk_ThunkConnect32 sempre que é chamado DllMain, tal como mostrado aqui ("thk" é o prefixo do compilador thunk - t parâmetro):
       // 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 secção EXPORTS do ficheiro módulo (.def) de definição para a DLL de 32 bits:
    thk_ThunkData32
    						
  3. Exporte as funções às quais estão thunking. Pode utilizar o ficheiro de definição (DEF) do módulo a DLL de 32 bits ou a palavra-chave __declspec(dllexport). Certifique-se que são declarados e definidos como __stdcall. Se a DLL de 32 bits for escrita em C++, não se esqueça declará-los como bem externo "C". Estas funções são chamadas pelo lado do thunk 16 bits.
  4. Compilar o script thunk maneira (se ainda não compilada):
    thunk -t thk 16to32.thk -o 16to32.asm
    						
  5. Monte o ficheiro de linguagem assembly produzido pelo compilador thunk como um módulo de objecto de 32 bits. A linha seguinte mostra um exemplo:
    ml /DIS_32 /c /W3 /nologo /coff /Fo thk32.obj 16to32.asm
    						
  6. Ligar este módulo de objecto como parte da DLL de 32 bits.
  7. Ligar thunk32.lib como parte da DLL de 32 bits. Esta é a biblioteca de importação de 32 bits fornecida no Win32 SDK que contém referências a API thunking a 32 bits que utiliza o código criado pelo compilador thunk.

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 plano

A informação contida neste artigo aplica-se a:
  • Microsoft Win32 Application Programming Interface 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 revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes 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 ArticleExclusão de Responsabilidade para Conteúdo sem Suporte na KB
Este artigo foi escrito sobre produtos para os quais a Microsoft já não fornece suporte. Por conseguinte, este artigo é oferecido "tal como está" e deixará de ser actualizado.