Компоновка смешанных модулей
Что произойдет, если вы компилируете один модуль с использованием модели памяти small (малая), второй - модели large (большая), и затем хотите скомпоновать их? Что при этом произойдет?
Файлы скомпонуются удовлетворительно, но при этом вы столкнетесь с проблемами. Если функция модуля с моделью small вызывает
функцию в модуле с моделью large, она будет использовать при этом
ближний вызов, что даст абсолютно неверные результаты. Кроме того, у вас возникнут проблемы с указателями, описанные в разделе
"Объявление указателей как near, far или huge", поскольку функция
в модуле small ожидает, что принимаемые и передаваемые ей указатели будут __near, тогда как функция в модуле large ожидает работу с указателями __far.
И снова решение заключается в использовании прототипов функций. Предположим, что вы поместили myputs в отдельный модуль и
скомпилировали его с моделью памяти large. Затем вы создаете файл
заголовка myputs.h (либо с любым другим именем и расширением .h),
который содержит следующий прототип функции:
void far myputs(char far *s);
Теперь, если поместить функцию main в отдельный модуль
(MYMAIN.C) и выполнить следующие установки:
#include <stdio.h>
#include "myputs.h"
main()
{
char near *mystr;
mystr = "Hello, world\n";
myputs(mystr);
}
то при компиляции данной программы Borland C++ считает прототип
функции из файла MYPUTS.H и увидит, что это функция __far, ожидающая указатель __far. В результате этого даже при модели памяти
small при компиляции будет сгенерирован правильный вызывающий
код.
Как быть, если помимо этого вам требуется компоновка с библиотечными подпрограммами? Лучший подход здесь заключается в том,
чтобы выбрать одну из библиотек с моделью large и объявить все
как far. Для этого сделайте копии всех файлов заголовка, которые
вы обычно включаете (таких, как stdio.h) и переименуйте эти копии
(например, fstdio.h).
Затем отредактируйте копии прототипов функций таким образом,
чтобы там было явно указано far, например:
int far cdecl printf(char far* format, ...);
Тем самым, не только вызовы подпрограмм будут дальними, но и
передаваемые указатели также будут дальними. Модифицируйте вашу
программу таким образом, чтобы она включала новый файл заголовка:
#include <fstdio.h>
main()
{
char near *mystr;
mystr = "Hello, world\n";
printf(mystr);
}
Скомпилируйте вашу программу при помощи компилятора BCC, затем скомпонуйте ее при помощью утилиты TLINK, указав библиотеки с
моделью памяти large, например CL.LIB. Смешивание модулей с разными моделями - вещь экстравагантная, но допустимая. Будьте, однако, готовы к тому, что любые неточности здесь приводят к ошибкам, которые очень трудно найти и исправить при отладке.
Назад | Содержание | Вперед