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

Рисунок 1.4 показывает, как использовать классы-дескрипторы для отделения интерфейса от реализации на этапе выполнения. Заметим, что косвенный подход, введенный классом интерфейса, устанавливает двоичную защитную стену (firewall – брандмауэр) между клиентом и реализацией объекта. Эта двоичная стена очень точно описывает, как клиент может сообщаться с реализацией. Все связи клиент-объект осуществляются через класс интерфейса, который содержит очень простой двоичный протокол для входа в область реализации объекта. Этот протокол не содержит никаких деталей класса реализации в C++.

Хотя методика использования классов-дескрипторов имеет свои преимущества и безусловно приближает нас к возможности безопасного извлечения классов из DLL, она также имеет свои недостатки. Отметим, что класс интерфейса вынужден явно передавать каждый вызов метода классу реализации. Для простого класса вроде FastString только с двумя открытыми операторами, конструктором и деструктором, это не проблема. Для большой библиотеки классов с сотнями или тысячами методов написание этих передающих процедур было бы весьма утомительным и явилось бы потенциальным источником ошибок. Кроме того, для областей с повышенными требованиями к эффективности программ (performance-critical domains), цена двух вызовов для каждого метода (один вызов на интерфейс, один вложенный вызов на реализацию) весьма высока. Наконец, методика классов-дескрипторов не полностью решает проблемы совместимости транслятора/компоновщика, а они все же должны быть решены, если мы хотим иметь основу, действительно пригодную для создания компонентов повторного использования.

<p>Абстрактные базы как двоичные интерфейсы</p>

Оказывается, применение техники разделения интерфейса и реализации может решить и проблемы совместимости транслятора/компоновщика C++. При этом, однако, определение класса интерфейса должно принять несколько иную форму. Как отмечалось ранее, проблемы совместимости возникают из-за того, что разные трансляторы имеют различные соображения по поводу того, как

1. передавать особенности языка на этапе выполнения;

2. символические имена будут представлены на этапе компоновки.

Если бы кто-нибудь придумал, как скрыть детали реализации транслятора/компоновщика за каким-либо двоичным интерфейсом, это сделало бы написанные на C++ библиотеки DLL значительно более широко используемыми.

Двоичная защита, то есть тот факт, что класс интерфейса C++ не использует языковых конструкций, зависящих от транслятора, решает проблему зависимости от транслятора/компоновщика. Чтобы сделать эту независимость более полной, необходимо в первую очередь определить те аспекты языка, которые имеют одинаковую реализацию в разных трансляторах. Конечно, представление на этапе выполнения таких сложных типов, как С-структуры (structs), может быть выдержано инвариантным по отношению к трансляторам. Это – основное, что должен делать системный интерфейс, основанный на С, и иногда это достигается применением условно транслируемых определений типа прагм (pragmas) или других директив транслятора. Второе, что следует сделать, – это заставить все компиляторы проходить параметры функций в одном и том же порядке (слева направо, справа налево) и зачищать стек также одинаково. Подобно совместимости структур, это также решаемая задача, и для унификации работы со стеком часто используются условные директивы транслятора. В качестве примера можно привести макросы WINAPI/WINBASEAPI из Win32 API. Каждая извлеченная из системных DLL функция определена с помощью этих макросов:

WINBASEAPI void WINAPI Sleep(DWORD dwMsecs);

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

Третье требование к независимости трансляторов – наиболее уязвимое для критики из всех, так как оно делает возможным определение двоичного интерфейса: все трансляторы C++ с заданной платформой одинаково осуществляют механизм вызова виртуальных функций. Действительно, это требование единообразия применимо только к классам, не имеющим элементов данных, а имеющим не более одного базового класса, который также не имеет элементов данных. Вот что означает это требование для следующего простого определения класса:

class calculator

{

public: virtual void add1(short x);

virtual void add2(short x, short y);

};

Все трансляторы с данной платформой должны создать эквивалентные последовательности машинного кода для следующего фрагмента программы пользователя:

extern calculator *pcalc;

pcalc->add1(1);

pcalc->add2(1, 2);

Перейти на страницу:

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

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных