Как вызывать 16-битный код из 32-битного под Windows 95Возможно, Вам как разработчику, иногда
необходимо работать с 16-битными динамическими
библиотеками (DLL) из приложения Win32. Особенно это
важно, когда нет исходного кода DLL, которую
необходимо портировать в Win32. В данной статье
описывается механизм, при помощи которого
32-битные DLL могут вызывать 16-битными DLL. Этот
механизм называется "thunk" а метод,
включённый в Windows 95 называется "flat thunk".
Flat thunk состоит из 32-битной и 16-битной DLL, которые
работают вместе. Приложение Win32 работает с
32-битной DLL, а 32-битная DLL в свою очередь вызывает
экспортированные функции в 16-битной DLL. Когда
функция в 16-битной DLL завершает выполнение, то она
возвращает управление обратно в 32-битную DLL,
которая в свою очередь возвращает управление
обратно в приложение Win32. 32-битные и 16-битные DLL
работают вызывая 32-битное и 16-битное ядро в Windows 95
соответственно, для обработки необходимых
деталей низкого уровня, чтобы создать переход от
32-битного в 16-битный код и обратно. +------------+
| 32to16.thk |
+------------+
|
+------------+
| 32to16.asm |
+------------+
/ \
-DIS_32 / \ -DIS_16
/ \
+-----------+ +-----------+
| 32THK.obj | | 16THK.obj |
+-----------+ +-----------+
/ \
+-------+ +-------+ +-------+
| APP32 | -> | DLL32 | -- THUNK -- | DLL16 |
+-------+ +-------+ +-------+
Инструменты, необходимые для создания Flat Thunk
Создание Thunk скриптаВам необходимо создать скрипт, который может
быть использован в Thunk компиляторе для создания
thunk. Thunk скрипт, это текстовый файл, который
содержит объявление типов, прототипы функций,
которые Вы хотите вызывать через thunk-и, а так же
спецификацию направления параметров для каждой
функции. Например, некоторые функции требуют как
входные так и выходные параметры, в то время, как
другие нуждаются только во входных параметрах.
Thunk скрипт использует специальный синтаксис для
описания, какого типа параметры будут: только
входные, только выходные, или как входные, так и
выходные.
Thunk компилятор ожидает, что 32-битная часть thunk
объявлена как __stdcall, а 16-битная как __far __pascal.
(Объявление WINAPI заботится об обоих частях.) __cdecl и
__fastcall не поддерживаются Thunk компилятором.
Обратите внимание, что вообщето Thunk компилятор не
понимает ключевые слова __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 = output" говорит Thunk
компилятору, что 16-битная функция возвращает
адрес, который должен быть конвертирован из
указателя selector:offset в 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" говорит компилятору скрипта, что этот указатель будет использоваться для входа и выхода. Это заставляет Thunk компилятор преобразовать lpCircleInOut из 32-битного линейного адреса в указатель selector:offset при вызове функции и обратно в 32-битный линейный адрес, когда функция возвращает управление. Преобразование делает thunk, созданный Thunk компилятором. Использование Thunk компилятораПараметры Thunk компилятора следующие:
Следующая командная строка показывает, как компилировать 32->16 thunk скрипт. Входным файлом является thunk скрипт с именем 32to16.thk, в итоге появится файл на ассемблере с именем 32to16.asm.
Опция "-t thk" указывает Thunk компилятору, чтобы тот делал префикс "thk_." для thunk функций в ассемблерном файле. Этот префик используется когда компонуется несколько thunk скриптов в пару DLL, и используется при создании пары DLL, которые содержат как 32->16 так и 16->32 thunk-и. Каждый thunk скрипт должен иметь уникальный префикс. Создание 32-битной DLL
Создание 16-битной DLL
ССЫЛКИИнформацию о том, как отлаживать flat thunks смотрите в статье из Microsoft Knowledge Base: Q133722 Как отлаживать Flat Thunks
|