Cómo llamar a código de 16 bits desde código de 32 bits en Windows 95, Windows 98 y Windows Millennium Edition

Seleccione idioma Seleccione idioma
Id. de artículo: 155763 - Ver los productos a los que se aplica este artículo
Expandir todo | Contraer todo

En esta página

Resumen

Como desarrollador, quizás tenga acceso a la funcionalidad proporcionada por un 16-bit dynamic-link biblioteca (DLL) desde la aplicación de Win32. Esto ocurre especialmente cuando no tiene el código fuente para el archivo DLL para que los puede trasladar a Win32. En este artículo se describe el mecanismo por el que las DLL de 32 bits pueden llamar a archivos DLL de 16 bits. El mecanismo se denomina un thunk y el método implementado en Microsoft Windows 95, Windows 98 y Windows Millennium Edition se denomina un thunk plano.

A continuación describe los tres principales pasos de creación de un thunk plano:
  1. Crear la secuencia de comandos thunk.
  2. Genere la DLL de 32 bits.
  3. Genere la DLL de 16 bits.

Más información

Un thunk plano consta de 32 bits y una DLL de 16 bits que funcionan conjuntamente. Una aplicación Win32 llama a la DLL de 32 bits, y la DLL de 32 bits llama a una función exportada en el archivo DLL de 16 bits. Cuando se devuelve la función en la DLL de 16 bits, devuelve a la DLL de 32 bits, que a su vez devuelve a la aplicación de Win32. El trabajo de DLL de 32 bits y 16 bits llamando a los núcleos de Windows 95 de 32 bits y 16 bits para controlar todos los detalles de bajo nivel necesarios para realizar la transición desde código de 32 bits a 16 bits y de nuevo.

Diseñar un thunk plano nuevo implica crear una secuencia de comandos de thunk (.thk archivo). Esta secuencia de comandos se compila con el compilador de procesador en un archivo de lenguaje ensamblador, que a continuación, se ensambla dos veces; una vez con cada uno de dos indicadores de - DIS_32 y - DIS_16. Esto le permite crear ambos los módulos de objeto de 32 bits y 16 bits. Estos módulos de objeto están vinculados en la DLL de 32 bits y 16 bits, respectivamente. El siguiente diagrama resume los archivos implicados en generar los archivos DLL:
                         +------------+
                         | 32to16.thk |
                         +------------+
                               |
                         +------------+
                         | 32to16.asm |
                         +------------+
                           /         \ 
                  -DIS_32 /           \ -DIS_16
                        /              \ 
                  +-----------+  +-----------+
                  | 32THK.obj |  | 16THK.obj |
                  +-----------+  +-----------+
                        /                 \ 
        +-------+    +-------+             +-------+
        | APP32 | -> | DLL32 | -- THUNK -- | DLL16 |
        +-------+    +-------+             +-------+
				

Herramientas necesarias para generar procesadores fijo

  • Microsoft Visual C++ versión 1.5 x del compilador (16 bits) del lado de 16 bits de crear el código thunk. El lado de 16 bits del código thunk es una DLL de 16 bits.
  • Microsoft Visual C++ versión 2.x o compilador superior de (32 bits) para crear el lado de 32 bits del código thunk. El lado de 32 bits del código thunk es una DLL de 32 bits.
  • Compilador de procesador (Thunk.exe) del SDK de Microsoft Win32 para compilar el código thunk de secuencias de comandos.
  • Microsoft Macro Assembler (MASM) 6.1 o posterior para ensamblar el resultado de lenguaje ensamblador del compilador de procesador.
  • Rc.exe de 16 bits archivo de directorio de Microsoft Win32 SDK BINW16 para marcar el código thunk de 16 bits DLL como versión 4.0.

Crear la secuencia de comandos procesador

Tiene que crear una secuencia de comandos que puede utilizar el compilador de procesador para crear un thunk. Una secuencia de comandos thunk es un archivo de texto que contiene definiciones de tipo, los prototipos de función de las funciones que desea llamar a través de los procesadores y una especificación de la dirección de los parámetros para cada función. Por ejemplo, algunas funciones requieren parámetros de entrada y salida, mientras que otros sólo pueden requerir parámetros de entrada. Las secuencias de comandos thunk utilizan sintaxis especial para describir si los parámetros son de entrada, salida, o en entrada y salida.

Un script de thunk para 32-> 16 thunks comienza con la siguiente instrucción:
enablemapdirect3216 = true;
El compilador de procesador se espera que el lado de 32 bits del código thunk se declara como __stdcall, y que el lado de 16 bits es __pascal __far. (La declaración WINAPI se ocupa de esto en ambos lados.) __Cdecl las convenciones de llamada __fastcall no son compatibles con el compilador de procesador. Sin embargo, tenga en cuenta que el compilador de procesador Aceptar realmente las palabras clave __far, __pascal o __stdcall; se supone que son.

Ejemplo siguiente muestra una secuencia de comandos thunk para una función que no tiene parámetros:
   enablemapdirect3216 = true;

   void MyThunk16()
   {
   }
				
la declaración equivalente sería:
   C   language:  void WINAPI MyThunk16(void);
   C++ language:  extern "C" void WINAPI MyThunk16();
				
el script de ejemplo siguiente describe una función que toma dos parámetros y devuelve un valor. El segundo parámetro es un parámetro de salida que contiene un puntero que se pasa la DLL de 32 bits.
   enablemapdirect3216 = true;

   typedef int   BOOL;
   typedef char *LPSTR;

   BOOL MyThunk16(LPSTR lpstrInput, LPSTR lpstrOutput)
   {
      lpstrInput  = input;    // optional; input is default
      lpstrOutput = output;
   }
				
la instrucción "lpstrOutput = salida" indica al compilador de procesador que la función de 16 bits devuelve una dirección que necesita para convertirse de un puntero de desplazamiento: selector en una dirección lineal de 32 bits.

La siguiente secuencia de comandos thunk utiliza tipos de parámetro más complejas, como estructuras. En este ejemplo también muestra cómo especificar parámetros de entrada y salida.
   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;
   }
				
la instrucción "lpCircleInOut = inout" indica al compilador de secuencias de comandos que este puntero se va a utilizar para la entrada y salida. Esto hace que el compilador de procesador convertir lpCircleInOut desde una dirección lineal de 32 bits a un puntero de selector: desplazamiento cuando se llama a la función y vuelva a una dirección lineal de 32 bits cuando se devuelve la función. La conversión se controla mediante el código thunk creado por el compilador de procesador.

Mediante el compilador de procesador

El uso del compilador de procesador es como sigue:
thunk.exe opciones <outputfile> <inputfile> -o
La siguiente línea de comandos muestra cómo compilar un 32-> 16 secuencia de comandos thunk. Esta línea toma una secuencia de comandos thunk denominado 32to16.thk y genera un archivo de lenguaje ensamblador llamado 32to16.asm.
procesador -t thk 32to16.thk -o 32to16.asm
El "-t thk" opción indica al compilador procesador prefijo las funciones de thunk en el archivo de lenguaje ensamblador con "thk_." Este prefijo se utiliza al relacionar varias secuencias de comandos thunk en un par de archivos DLL y es útil para crear un par de archivos DLL que contienen ambas 32-> 16 y 16-> 32 procesadores. Cada secuencia de comandos thunk debe tener un prefijo único.

Creación de la DLL de 32 bits

  1. En la función DllMain del archivo DLL de 32 bits, debe realizar una llamada a una función creada por el compilador de procesador denominado thk_ThunkConnect32 para que se llama a cada razón (dwReason) DllMain, tal como se muestra aquí ("thk" es el prefijo del modificador -t de compilador de procesador):
          // prototype for function in .obj file from the thunk script
          BOOL WINAPI thk_ThunkConnect32(LPSTR     lpDll16,
                                         LPSTR     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. Incluye las siguientes líneas en la sección EXPORTS del archivo de definición (.def) de módulo para el archivo DLL de 32 bits. Por ejemplo:
          
       thk_ThunkData32
    						
  3. Exportar las funciones que llama la aplicación de Win32. Puede utilizar archivo de definición (.def) del módulo de la DLL de 32 bits o la palabra clave __declspec (dllexport). Asegúrese de que las funciones se declara y definidas como __stdcall (o WINAPI). Si la DLL de 32 bits está escrita en C++, asegúrese de declarar las funciones como extern "C".
  4. Compilar la secuencia de comandos thunk como sigue (si no está compilado):
          thunk -t thk 32to16.thk -o 32to16.asm
    						
  5. Ensamblar el archivo de lenguaje ensamblador generado por el compilador de procesador como un módulo de objeto de 32 bits. Por ejemplo:
          ml /DIS_32 /c /W3 /nologo /coff /Fo thk32.obj 32to16.asm
    						
  6. Vincular este módulo de objeto como parte de la DLL de 32 bits.
  7. Vincular la biblioteca Thunk32.lib como parte de la DLL 32-bit. Se trata de la biblioteca de importación 32-bit proporcionada en el Win32 SDK que contiene referencias a las API de thunk 32-bit que utiliza el código creado por el compilador de procesador.

Creación de la DLL de 16 bits

  1. La DLL de 16 bits debe exportar una función denominada "DllEntryPoint." Esta función debe realizar una llamada a una función creada por el compilador de procesador denominado thk__ThunkConnect16 ("thk" es el prefijo del modificador -t de compilador de procesador) cada vez que se llama DllEntryPoint:
          // prototype for function in .obj file from the thunk script
          BOOL WINAPI __export thk_ThunkConnect16(LPSTR lpDll16,
                                                  LPSTR lpDll32,
                                                  WORD  hInst,
                                                  DWORD dwReason);
    
          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. Incluir las líneas siguientes en la sección IMPORTS del archivo de definición (.def) de módulo para el archivo DLL de 16 bits. Por ejemplo:
          C16ThkSL01      = KERNEL.631
          ThunkConnect16  = KERNEL.651
    						
  3. Incluye las siguientes líneas en la sección EXPORTS del archivo de definición (.def) de módulo para el archivo DLL de 16 bits. THK_THUNKDATA16 se define en el archivo de objeto que es ensamblado desde el resultado del compilador de procesador. Ambos de estos símbolos deben tener la palabra clave RESIDENTNAME, pero pueden tener cualquier número ordinal.
          THK_THUNKDATA16 @1  RESIDENTNAME
          DllEntryPoint   @2  RESIDENTNAME
    						
  4. Agregue funciones thunk a la instrucción EXPORTS del archivo de definición (.def) del módulo de la DLL de 16 bits. Asegúrese de que son declarados y definidos como __pascal __far __export (o WINAPI __export). Si la DLL está escrita en C++, asegúrese de declararlas como extern "C". El lado de 32 bits de thunk llama a estas funciones.
  5. Compilar la secuencia de comandos thunk como sigue (si no está compilado):
          thunk -t thk 32to16.thk -o 32to16.asm
    						
  6. Ensamblar el archivo de lenguaje ensamblador generado por el compilador de procesador como un módulo de objeto de 16 bits. Por ejemplo:
          ml /DIS_16 /c /W3 /nologo /Fo thk16.obj 32to16.asm
    						
  7. Vincular este módulo de objeto como parte de la DLL de 16 bits.
  8. Marque la DLL de 16 bits como versión 4.0. Para ello, utilice el compilador de recursos (rc.exe). La siguiente línea muestra la sintaxis:
    rc entre -40 < archivo DLL >
    Esta opción de entre-40 está disponible en el compilador de recursos se proporciona con el SDK de Win32.

    Nota : asegúrese de utilizar el archivo de RC.exe en el directorio BINW16 para que el archivo DLL se marquen con la versión 4.0. El archivo de RC.exe que se incluye con las versiones de 16 bits de Microsoft Visual C++ no marca el archivo DLL como versión 4.0.

Referencias

Para obtener información acerca de cómo depurar los procesadores sencillos, consulte el siguiente artículo en Microsoft Knowledge Base:
133722Cómo depurar procesadores fijo

Propiedades

Id. de artículo: 155763 - Última revisión: lunes, 11 de julio de 2005 - Versión: 2.3
La información de este artículo se refiere a:
  • Microsoft Win32 Application Programming Interface sobre las siguientes plataformas
    • Microsoft Windows 95
    • Microsoft Windows 98 Standard Edition
    • Microsoft Windows Millennium Edition
    • Microsoft Platform Software Development Kit-January 2000 Edition
Palabras clave: 
kbmt kbapi kbhowto kbkernbase kbnetwork kbprogramming kbthunks kbtshoot KB155763 KbMtes
Traducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 155763

Enviar comentarios

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com