Введение в XPCOM

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

Уже достаточно давно (а по меркам всемирной истории - наоборот, совсем недавно) программисты пришли к идее объектно-ориентированного программирования. Об этой важной и, бесспорно, очень удачной концепции можно найти сведения в любом учебнике по любому более-менее современному языку программирования. Успех этой концепции во многом определялся её эффективностью: приложения, написанные в объектно-ориентированном стиле, проще создавать и отлаживать, соответственно, и себестоимость у них меньше.

Однако зачастую возникала необходимость создания приложений из нескольких "кусков", написанных на разных языках. И вот тут начинались настоящие приключения. Каждый компонент приложения был написан на своём языке, и у каждого языка были свои стандарты для внутреннего представления объектов в программе. Поэтому в каждом компоненте приходилось создавать специальные интерфейсы для связи с другими компонентами. Это было не слишком удобно, да и не очень-то и надёжно. Поэтому возникли технологии, позволяющие осуществлять межкомпонентное взаимодействие через объектно-ориентированные интерфейсы. Самая известная из них - это Microsoft COM. Технология полезная и популярная, и даже, пожалуй, одна из лучших технологий, разработанных корпорацией Microsoft. Единственный серьёзный минус этой технологии состоит в том, что она не переносима на другие платформы, кроме Windows. То есть, конечно, при желании её перенести можно, и существуют эмуляторы, позволяющие пользоваться COM'ом на различных платформах. Но это не очень удобно и не совсем законно. Поэтому COM для кросс-платформенных приложений не подходит.

К счастью, COM - не единственный способ связи между компонентами приложения при помощи объектов. В качестве альтернативного решения я хочу предложить вам XPCOM - технологию, успешно использующуюся в таких разработках, как Netscape Browser, Mozilla Firefox и OpenOffice.org. Разработала эту технологию корпорация Netscape на вершине своей славы и своего могущества, а сейчас владельцем прав на неё является фонд Mozilla.

Итак, что же такое XPCOM? Как говорят сами разработчики, это кросс-платформенный аналог технологии Microsoft COM, позволяющий не только разрабатывать приложения, собранные из отдельных независимых компонентов, но и управлять памятью, абстрагироваться от уровня отдельных файлов (имеется в виду, динамических библиотек) и осуществлять обмен объектно-ориентированными сообщениями между компонентами.

Число платформ, на которых XPCOM умеет работать, довольно велико и включает в себя большинство широко распространённых сегодня операционных систем. На официальном сайте разработчиков технологии (developer.mozilla.org) называются следующие платформы: Microsoft Windows, GNU/Linux, HP-UX, AIX, Solaris, OpenVMS, Mac OS X, *BSD. Список платформ, на которых XPCOM теоретически работоспособен, но до конца не протестирован, ещё обширнее. Думаю, разработчиков кросс-платформенных приложений сей факт не может не радовать.

Теперь давайте об основных концепциях, использующихся при программировании для XPCOM. В общем-то, тем, кто имеет опыт программирования под Win32 с использованием технологии COM, скорее всего, будет всё понятно. Однако, по опыту некоторых своих знакомых, я знаю, что программистам, занимавшимся системным программированием под тот же Linux, часто бывает не просто понять идеологию XPCOM. Конечно, мудрый руководитель проекта никогда не станет ставить такого программиста на написание кода компонентов или, хуже того, на написание главного модуля, который этими компонентами управляет. Тем не менее, в нашей стране авралов и не такое случается, поэтому я всё же расскажу самую малость подробнее о самом главном термине, употребляющемся при работе с XPCOM.

Ключевое слово звучит знакомо для любого компьютерщика: интерфейс. Только когда мы говорим об интерфейсах применительно к XPCOM (или Microsoft COM), мы подразумеваем совсем не то же самое, что при словах "у этой программы красивый интерфейс". В данном случае под интерфейсом понимается описание набора методов данного класса. Это описание может соответствовать не одному, а нескольким разным классам - собственно, так бывает почти всегда, потому что в этом и есть смысл технологий компонентного программирования. Интерфейс нужен для того, чтобы клиент мог знать возможности вызываемых методов для классов компонента, и мог им передавать нужные параметры. При этом компонент должен гарантированно реализовывать все методы, описываемые всеми интерфейсами, которые он поддерживает. То есть, любой вызов любого метода любого из этих компонентов должен корректно выполняться. Само собой, интерфейс может не описывать всех методов объекта, но те из них, которые им описываются, у объекта точно присутствуют. В C++, с использованием которого пишется большинство компонентов XPCOM, интерфейсы реализуются в виде абстрактных классов. Возможно, кто-то заметит, что было бы логичнее использовать шаблоны Классов. Однако это, к сожалению или к счастью, невозможно, поскольку "стыковка" компонентов с использующим их клиентом осуществляется не на этапе компиляции, а уже на этапе выполнения приложения.

По аналогии с COM, в XPCOM употребляется технология счётчиков ссылок. Компонент, реализующий интерфейсы, ведёт автоматический подсчёт клиентских ссылок на себя, любимого. Как только количество их станет равным нулю, придёт время ему уничтожиться. В этом нелёгком деле компоненту помогают интерфейсы. Как и в технологии Microsoft COM, каждый интерфейс в XPCOM должен поддерживать три основные функции, описанные в базовом интерфейсе nsISupports (обратите, кстати, внимание, на префикс ns - как вы думаете, не от слова ли Netscape это сокращение?). Функции, обязательные для всех интерфейсов, занимаются самыми нужными вещами. QueryInterface отвечает за получение от объекта правильного интерфейса, AddRef увеличивает количество значений счётчика ссылок (а уменьшается оно автоматически при уничтожении ссылающихся на объект клиентов), а уничтожает ненужные объекты функция Release. Прошу обратить внимание, что, несмотря на то, что я использую термин "функция" для большей наглядности, правильнее было бы всё же пользоваться термином "метод", поскольку речь идёт о классах.

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

Как и в COM, в XPCOM используются уникальные идентификаторы классов - 128-битные целые числа. С их помощью осуществляется доступ к классам компонента со стороны клиента. При этом параллельно используются "идентификаторы контрактов", которые являются строковыми величинами. Вот пример такого идентификатора: "@mozilla.org/network/ldap-operation;1". Как видите, он разбит на несколько вполне осмысленных частей: сначала идёт домен компонента (т.е. его владелец), затем - имя модуля, имя компонента и его версия. Эти идентификаторы используются при обращении к компонентам, однако, в отличие от идентификаторов класса, они не привязаны к конкретному интерфейсу или классу, а относятся ко всему компоненту целиком.

Для описания интерфейсов используется язык описания интерфейсов XPIDL, являющийся одним из диалектов утверждённого консорциумом CORBA языка Interface Definition Language (IDL). С помощью этого языка можно задать методы для каждого интерфейса и специфические константы, к нему относящиеся. При этом стоит помнить, что интерфейсы поддерживают наследование. После написания XPIDL-файла его нужно скомпилировать специальным компилятором, который можно найти на сайте разработчиков. В общем, всё как в случае MS COM.

Как я уже говорил, сама парадигма технологии XPCOM подразумевает совместимость её со многими языками программирования. На сайте developer.mozilla.org можно найти заголовочные файлы для использования XPCOM из программ, написанных на Python, Java, Ruby, Perl и даже JavaScript. Как видите, здесь разработчики тоже постарались перенять максимум всего полезного от технологии COM, которая также даёт равные права для интерпретируемых и компилируемых языков. Таким образом, XPCOM может стать довольно изящным решением, если есть нужда в написании кросс-платформенного приложения сразу на нескольких из перечисленных языков. Правда, стоит заметить, что с JavaScript XPCOM работает только в одну сторону: вызывать из JavaScript'а XPCOM-компоненты можно, а вот писать на нём свои не получится.

Что ж, полагаю, изложенных материалов вполне достаточно для того, чтобы в общих чертах понять, что представляет собой технология XPCOM. Более детальному знакомству поможет изрядное количество электронной документации на сайте разработчиков технологии (правда, вся она на английском языке). Ну и, конечно же, не обойтись без практики.

Впрочем, последнее утверждение безо всяких оговорок применимо не только к XPCOM, но и к любой другой технологии и вообще ко всем знаниям.

(Продолжение следует)

Вадим СТАНКЕВИЧ

Версия для печатиВерсия для печати

Номер: 

43 за 2006 год

Рубрика: 

Software
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!

Комментарии

Аватар пользователя Dmitry
Привет, Вадим!

Предже всего -- спасибо за твои статьи. Читаю их с удовольствием...

Предлагаю в будущем пролить свет на Eclipse (http://www.eclipse.org/) и его популярные дополнения:

- CDT (http://www.eclipse.org/cdt/)

- WTP (http://www.eclipse.org/webtools/)

- EPIC (http://e-p-i-c.sourceforge.net/)

- JBoss (http://labs.jboss.com/portal/jbosside/?prjlist=false)

Аватар пользователя Вадим Станкевич
Спасибо! Постараюсь.