Четвертый BORLAND С++ и его окружение

       

Компоновка смешанных модулей


Что произойдет, если вы компилируете один модуль с использованием модели памяти 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. Смешивание модулей с разными моделями - вещь экстравагантная, но допустимая. Будьте, однако, готовы к тому, что любые неточности здесь приводят к ошибкам, которые очень трудно найти и исправить при отладке.



Содержание раздела