Как позвонить 16-разрядного кода из 32-разрядного кода В Windows 95, Windows 98 и Windows Me

Переводы статьи Переводы статьи
Код статьи: 155763 - Vizualiza?i produsele pentru care se aplic? acest articol.
Развернуть все | Свернуть все

В этой статье

Аннотация

Разработчику может потребоваться доступ к функциональности, предоставляемой библиотекой 16-разрядные динамической компоновки (DLL) в приложении Win32. Это верно, особенно если у вас нет исходного кода для библиотеки DLL, можно перенести его в Win32. В данной статье рассматривается механизм, по которому 32-разрядных библиотеках DLL, может вызывать 16-разрядных библиотеках DLL. Механизм называется преобразователь и метод, реализованный под управлением Microsoft Windows 95, Windows 98 и Windows Millennium Edition называется простой преобразователь.

Ниже описаны три основные этапы создания простой преобразователь.
  1. Создайте сценарий преобразователь.
  2. Создание 32-разрядные библиотеки DLL.
  3. Построение 16-разрядные библиотеки DLL.

Дополнительная информация

Плоский преобразователь состоит из 32-разрядных и 16-разрядные библиотеки DLL, работающих вместе. Приложения Win32 вызывает DLL 32-разрядных и 32-разрядные библиотеки DLL вызывает экспортированную функцию в 16-разрядные библиотеки DLL. При возвращении в 16-разрядные библиотеки DLL функции возвращается обратно в 32-разрядные библиотеки DLL, которая в свою очередь возвращает в приложение Win32. 32-Разрядных и 16-разрядные библиотеки DLL работы путем вызова Windows 95 32-разрядных и 16-разрядные версии ядра для обработки всех низкоуровневых деталей, необходимых для перехода из 32 бит на 16-разрядного кода и обратно.

Разработка новых простой преобразователь включает создание сценария преобразователь (файл .thk). Этот сценарий компилируется с помощью компилятора преобразователь в файл языка ассемблера, который затем собраны дважды, один раз в каждой из двух флагов - DIS_32 и - DIS_16. Это позволяет создать объект 32-разрядных и 16-разрядные модули. Эти модули объектов связаны в 32-разрядных и 16-разрядных библиотеках DLL, соответственно. Следующая диаграмма перечислены файлы, используемые при построении библиотеки DLL.
                         +------------+
                         | 32to16.thk |
                         +------------+
                               |
                         +------------+
                         | 32to16.asm |
                         +------------+
                           /         \ 
                  -DIS_32 /           \ -DIS_16
                        /              \ 
                  +-----------+  +-----------+
                  | 32THK.obj |  | 16THK.obj |
                  +-----------+  +-----------+
                        /                 \ 
        +-------+    +-------+             +-------+
        | APP32 | -> | DLL32 | -- THUNK -- | DLL16 |
        +-------+    +-------+             +-------+
				

Средства, необходимые для создания плоской преобразователи

  • Microsoft Visual C++ версии 1.5 x компилятор (16 бит) для 16-разрядные части создание преобразователь. 16-Разрядные части преобразователь является 16-разрядные библиотеки DLL.
  • Microsoft Visual C++ версии 2.x или более компилятор (32-разрядная версия) для создания 32-разрядные части преобразователь. 32-Разрядные части преобразователь адресов — это 32-разрядные библиотеки DLL.
  • Преобразователь компилятору (Thunk.exe) Microsoft Win32 SDK для компиляции сценариев преобразователь.
  • Корпорация Майкрософт макрос Assembler (MASM) версии 6.1 или выше для объединяет выходные данные компилятора преобразователь языка ассемблера.
  • 16-разрядный файл Rc.exe из каталога BINW16 Microsoft Win32 SDK для маркировки преобразователь 16-разрядные библиотеки DLL с версии 4.0.

Создание сценария преобразователь

Необходимо создать сценарий, который может использоваться для создания преобразователь компилятором преобразователь. Преобразователь сценарий — это текстовый файл, который содержит определения типов, прототипы функций, функций, необходимо вызвать метод через преобразователи и спецификацию направления параметров для каждой функции. Например некоторые функции требуют как входные и выходные параметры, в то время как другие потребуется только входные параметры. Преобразователь сценарии используют специальный синтаксис для описания того, являются ли входные параметры, выходные данные, или оба входных и выходных данных.

Сценарий преобразователь 32-> 16 преобразователи начинается со следующей инструкции:
enablemapdirect3216 = true;
Преобразователь компилятор ожидает, что 32-разрядные части преобразователь объявляется как __stdcall, и что 16-разрядные части __far __pascal. (Объявление WINAPI берет на себя это с обеих сторон.) __Cdecl и соглашения о вызове __fastcall не поддерживается компилятором преобразователь. Обратите внимание, что компилятор преобразователь фактически не принимает __far, __pascal или __stdcall ключевых слов, то предполагается, что.

В следующем примере сценария преобразователь для функции, которая не имеет параметров.
   enablemapdirect3216 = true;

   void MyThunk16()
   {
   }
				
Эквивалентное объявление будет иметь вид:
   C   language:  void WINAPI MyThunk16(void);
   C++ language:  extern "C" void WINAPI MyThunk16();
				
В нижеприведенном примере сценария описаны функции, которая принимает два параметра и возвращает значение. Второй параметр является выходным параметром, который содержит указатель, который передается обратно в 32-разрядные библиотеки DLL.
   enablemapdirect3216 = true;

   typedef int   BOOL;
   typedef char *LPSTR;

   BOOL MyThunk16(LPSTR lpstrInput, LPSTR lpstrOutput)
   {
      lpstrInput  = input;    // optional; input is default
      lpstrOutput = output;
   }
				
Оператор "lpstrOutput = выходной» сообщает компилятору преобразователь, что 16-разрядные функция возвращает адрес, который должен быть преобразован из селектора: смещение указателя в 32-битный адрес линейной.

Следующий сценарий преобразователь использует более сложных типов параметров, таких как структуры. В этом примере также показано, как указать входные и выходные параметры.
   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;
   }
				
Оператор "lpCircleInOut = inout» сообщает компилятору сценарий, что этот указатель используется для ввода и вывода. В этом случае компилятор для преобразования lpCircleInOut из 32-битный адрес линейной указатель выделения: смещение, при вызове функции, а затем снова линейный 32-битный адрес, когда функция возвращает преобразователь. Преобразование обрабатывается преобразователь, созданным компилятором преобразователь.

С помощью компилятора преобразователь

Использование компилятора преобразователь выглядит следующим образом:
Thunk.exe /options <inputfile>-o <outputfile> </outputfile></inputfile>
Следующая командная строка показано, как скомпилировать 32-> 16 преобразователь сценария. Эта строка использует сценарий преобразователь с именем 32to16.thk и создает файл с именем 32to16.asm языка ассемблера.
преобразователь -t thk 32to16.thk -o 32to16.asm
"-T thk" параметр указывает компилятору преобразователь префикс функции преобразователь в файле языка ассемблера "thk_". Этот префикс используется при связывании нескольких сценариев преобразователь в пару библиотеки DLL и используется для создания пары из библиотеки DLL, содержащие оба 32-> 16 и 16-> 32 преобразователи. Каждый сценарий преобразователь должен иметь уникальный префикс.

Создание 32-разрядные библиотеки DLL

  1. В функции DllMain 32-разрядные библиотеки DLL, необходимо вызвать функцию, созданным компилятором преобразователь с именем thk_ThunkConnect32 называется все причины (dwReason) DllMain, как показано на рисунке («thk» — это префикс с параметром -t компилятор преобразователь):
          // 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. Включите следующие строки в разделе EXPORTS файла определения модуля (DEF) для 32-разрядные библиотеки DLL. Например,:
          
       thk_ThunkData32
    						
  3. Экспортируйте функции, вызываемые приложением Win32. Можно либо использовать 32-разрядные библиотеки DLL файла определения модуля (DEF) или ключевое слово __declspec(dllexport). Убедитесь, что объявления функций и определяются как __stdcall (или WINAPI). 32-Разрядные библиотеки DLL, написанные на C++, необходимо объявить как extern "C", так и функции.
  4. Сценарий преобразователь Скомпилируйте следующим образом (если он еще не скомпилирована):
          thunk -t thk 32to16.thk -o 32to16.asm
    						
  5. Создание файла языка ассемблера, созданный компилятором преобразователь как объект 32-разрядного модуля. Например,:
          ml /DIS_32 /c /W3 /nologo /coff /Fo thk32.obj 32to16.asm
    						
  6. Свяжите этот модуль объекта как часть 32-разрядные библиотеки DLL.
  7. Связывание библиотеки Thunk32.lib как часть 32-разрядные библиотеки DLL. Это происходит в Win32 SDK, который содержит ссылки для преобразования 32-разрядного API, код, созданный компилятором преобразователь использует библиотеку импорта 32-разрядные.

Создание 16-разрядные библиотеки DLL

  1. 16-Разрядные библиотеки DLL необходимо экспортировать функцию с именем «DllEntryPoint». Эту функцию необходимо вызвать функцию, созданным компилятором преобразователь с именем thk__ThunkConnect16 («thk» — это префикс с параметром -t компилятор преобразователь) при каждом вызове 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. Включают следующие строки в группе ИМПОРТ из файла определения модуля (DEF) для 16-разрядные библиотеки DLL. Например,:
          C16ThkSL01      = KERNEL.631
          ThunkConnect16  = KERNEL.651
    						
  3. Включите следующие строки в разделе EXPORTS файла определения модуля (DEF) для 16-разрядные библиотеки DLL. THK_THUNKDATA16 определен в объектном файле, построенный из выходных данных компилятора преобразователь. Оба эти символы должны иметь RESIDENTNAME ключевое слово, но может иметь любой порядковый номер.
          THK_THUNKDATA16 @1  RESIDENTNAME
          DllEntryPoint   @2  RESIDENTNAME
    						
  4. Добавьте преобразователь функции оператора EXPORTS из 16-разрядные библиотеки DLL файла определения модуля (DEF). Убедитесь, что они объявлены и определены как __far __pascal __export (или WINAPI __export). Если библиотека DLL написана на C++, необходимо объявить их как extern "C", так и. 32-Разрядные части преобразователь вызывает эти функции.
  5. Сценарий преобразователь Скомпилируйте следующим образом (если он еще не скомпилирована):
          thunk -t thk 32to16.thk -o 32to16.asm
    						
  6. Создание файла языка ассемблера, созданный компилятором преобразователь как объект 16-разрядного модуля. Например,:
          ml /DIS_16 /c /W3 /nologo /Fo thk16.obj 32to16.asm
    						
  7. Свяжите этот модуль объекта как часть 16-разрядные библиотеки DLL.
  8. Пометьте 16-разрядные библиотеки DLL с версии 4.0. Для этого используется компилятор ресурсов (Rc.exe). Указанную ниже показан синтаксис команды:
    от -40 RC<dll file=""> </dll>
    От-40 доступен в компилятор ресурсов, включенный в Win32 SDK.

    Примечание.: Будет использовать файл в каталоге BINW16 Rc.exe таким образом, чтобы DLL помечается версии 4.0. Rc.exe файл, который поставляется с 16-разрядных версий Microsoft Visual C++ не помечает Библиотеки в версии 4.0.

Ссылки

Для получения сведений о том, как отладка плоский преобразователями, обратитесь к следующей статье Microsoft Knowledge Base:
133722Как плоский преобразователи отладки

Свойства

Код статьи: 155763 - Последний отзыв: 14 ноября 2010 г. - Revision: 2.0
Информация в данной статье относится к следующим продуктам.
  • Microsoft Win32 Application Programming Interface на следующих платформах
    • Microsoft Windows 98 Standard Edition
    • операционная система Microsoft Windows Millennium Edition
Ключевые слова: 
kbapi kbhowto kbkernbase kbnetwork kbprogramming kbthunks kbtshoot kbmt KB155763 KbMtru
Переведено с помощью машинного перевода
ВНИМАНИЕ! Перевод данной статьи был выполнен не человеком, а с помощью программы машинного перевода, разработанной корпорацией Майкрософт. Корпорация Майкрософт предлагает вам статьи, переведенные как людьми, так и средствами машинного перевода, чтобы у вас была возможность ознакомиться со статьями базы знаний KB на родном языке. Однако машинный перевод не всегда идеален. Он может содержать смысловые, синтаксические и грамматические ошибки, подобно тому как иностранец делает ошибки, пытаясь говорить на вашем языке. Корпорация Майкрософт не несет ответственности за неточности, ошибки и возможный ущерб, причиненный в результате неправильного перевода или его использования. Корпорация Майкрософт также часто обновляет средства машинного перевода.
Эта статья на английском языке:155763

Отправить отзыв

 

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