Сущность технологии СОМ. Библиотека программиста - страница 10

Шрифт
Интервал

стр.


class _declspec(dllexport) FastString

{

char *m_psz;

public:

FastString(const char *psz);

~FastString(void);

int Length(void) const;

// returns # of characters

// возвращает число символов

int Find(const char *psz) const;

// returns offset

// возвращает смещение

};


В этом случае все методы FastString будут добавлены в список экспорта соответствующей библиотеки DLL, что позволит записать время выполнения каждого метода в его адрес в памяти. Кроме того, компоновщик создаст библиотеку импорта (import library), которая объявляет символы для методов FastString. Вместо того чтобы содержать сам код, библиотека импорта включает в себя ссылки на имя файла DLL и имена экспортируемых символов. Когда клиент обращается к библиотеке импорта, эти ссылки добавляются к исполняемой программе. Это побуждает загрузчик динамически загружать DLL FastString во время выполнения и размещать импортируемые символы в соответствующие ячейки памяти. Это размещение автоматически происходит в момент запуска клиентской программы операционной системой.

Рисунок 1.2 иллюстрирует модель FastString на этапе выполнения (runtime model), объявляемую из DLL. Заметим, что библиотека импорта достаточно мала (примерно вдвое больше, чем суммарный размер экспортируемого символьного текста). Когда класс экспортируется из DLL, код FastString должен присутствовать на жестком диске пользователя только один раз. Если даже несколько клиентов применяют этот код для своей библиотеки, загрузчик операционной системы обладает достаточным интеллектом, чтобы разделить физические страницы памяти, содержащие исполняемый код FastString (только для чтения), между всеми клиентскими программами. Кроме того, если разработчик библиотеки найдет дефект в исходном коде, теоретически возможно послать новую DLL конечному пользователю, исправляя дефектную реализацию для всех клиентских приложений сразу. Ясно, что перемещение библиотеки FastString в DLL является важным шагом на пути превращения класса C++ в заменяемый и эффективный компонент повторного использования.



C++ и мобильность

Поскольку вы решили распространять классы C++ как DLL, вы непременно столкнетесь с одним из фундаментальных недостатков C++ – недостаточной стандартизацией на двоичном уровне. Хотя рабочий документ ISO/ANSI C++ Draft Working Paper (DWP) предпринимает попытку определить, какие программы будут транслироваться и каковы будут семантические эффекты при их запуске, двоичная динамическая модель C++ ею не стандартизируется. Впервые клиент сталкивается с этой проблемой при попытке скомпоновать библиотеку импорта DLL FastString из среды развития C++, отличной от той, в которой он привык строить эту DLL.

Для обеспечения перегрузки операторов и функций компиляторы C++ обычно видоизменяют символическое имя каждой точки входа, чтобы разрешить многократное использование одного и того же имени (или с различными типами аргументов, или в различных областях действия) без нарушения работы существующих компоновщиков для языка С. Этот прием часто называют коррекцией имени. Несмотря на то что ARM (C++ Annotated Reference Manual) документировала схему кодирования, использующуюся в CFRONT, многие разработчики трансляторов предпочли создать свою собственную схему коррекции. Поскольку библиотека импорта FastString и DLL экспортирует символы, используя корректирующую схему того транслятора, который создал DLL (то есть GNU C++), клиенты, скомпилированные другим транслятором (например, Borland C++), не могут быть корректно скомпонованы с библиотекой импорта. Классическая методика использования extern "С" для отключения коррекции символов не поможет в данном случае, так как DLL экспортирует функции-члены (методы), а не глобальные функции.

Для решения этой проблемы можно проделать фокусы с клиентским компоновщиком, применяя файл описания модуля (Module Definition File), известный как DEF-файл. Одно из свойств DEF-файлов заключается в том, что они позволяют экспортируемым символам совмещаться с различными импортируемыми символами. Имея достаточно времени и информации относительно каждой схемы коррекции, разработчик библиотек может создать особую библиотеку импорта для каждого компилятора. Это утомительно, но зато позволяет любому компилятору обеспечить совместимость с DLL на уровне компоновки, при условии, что разработчик библиотеки заранее ожидал ее использование и создал нужный DEF-файл.


стр.

Похожие книги