Интернет, компьютеры, софт и прочий Hi-Tech

Подписаться через RSS2Email.ru

Руководство разработчика на IDL

Правила и синтаксис

XPIDL (XP1 Interface Description Language - Кросплатформенный язык описания интерфейсов) основан на спецификации OMG IDL, который используется для описания интерфейсов CORBA. XPIDL не является ни строгим подмножеством ни строгим расширением OMG IDL, поскольку в него включен некоторый специфичный для XPCOM синтаксис, при том что поддерживаются не все синтаксические конструкции OMG IDL. Этот раздел посвящен правилам XPIDL для описания интерфейсов. Посмотреть код C++, сгенерированный для данных здесь примеров, можно здесь.

Интерфейсы

Интерфейс объявляется с помощью ключевого слова interface. Ниже приведен простейший возможный интерфейс (код C++):

interface nsIFoo {
};

Для указания родительского интерфейса, его имя должно быть написано после имени определяемого интерфейса и двоеточия (код C++):

interface nsIFoo : nsIParent {
};

В XPCOM все интерфейсы имеют сопоставленный IID. Используйте синтаксис идентификационного атрибута для указания свойства uuid (код C++):

[uuid(00000000-0000-0000-c000-000000000046)]
interface nsIFoo : nsIParent {
};

Если вам нужна опережающая декларация интерфейса, просто опустите определение интерфейса, все данные о родителе и свойства (код C++):

interface nsIForward;

Методы и свойства

Интерфейс может иметь как методы, так и свойства. Свойства являются атрибутами объектов интерфейса, которые могут быть прочитаны и, возможно, установлены в некоторое значение. Ниже приводится интерфейс с одним методом (не имеищим параметров и не возвращающий значений), названным fun, и с целочисленным свойством, названным attr (код C++):

interface nsIFoo {
    attribute long attr;
    void fun();
};

Методы могут иметь любое число in-, out- и inout-параметров различных типов. Следующий интерфейс демонстрирует различные "in-out-ness"2 параметры различных типов (код C++):

interface nsIStringStuff {
  void findStringLength(in string str, out long l);
  void concatenateStrings(in string str1, in string str2,
                          out string result);
  void replaceChar(inout string str, in char from, in char to,
                   in boolean foldCase);
};

Вы можете указать возвращаемый тип для своего метода, отличный от void, но вы должны знать о правилах генерации кода. Возвращаемый не-void тип преобразуется в сгенерированном коде C++ в изменяемый параметр (out) (код C++):

interface nsINonVoidReturn {
  string gimmeString(in string str, in long count);
  long gimmeLong(in boolean prime);
};

Свойства могут быть объявлены как "только для чтения" с помощью ключевого слова readonly в определении (код C++):

interface nsIThing {
  readonly attribute string lookButDontTouch;
};

В C++ для атрибутов интерфейса автоматически декларируются методы Get и Set. Для атрибута с названием foo будут сгенерированы методы доступа GetFoo и SetFoo. Заметьте, что в названиях методов доступа первая буква названия атрибута была переведена в верхний регистр.

Код XPIDL Генерируемый заголовок C++
interface nsIBar {
  attribute short foo;
};
/* начало интерфейса:    nsIBar */
class nsIBar :  {
 public:

  /* attribute short foo; */
  NS_IMETHOD GetFoo(PRInt16 *aFoo) = 0;
  NS_IMETHOD SetFoo(PRInt16 aFoo) = 0;
};

Компилятор xpidl капитализирует названия методов в генерируемых заголовках C++. Это делается для поддержки существующих в Mozilla соглашений по C++, которые предусматривают ВерблюжачьюНотацию для названий методов. В JavaScript'е названия методов будут иметь ту же самую капитализацию, какая была использована в XPIDL. Согласно соглашениям, описанным в устоявшейся практике, названия методов в JavaScript следует писать в верблюжачейНотации.

Код XPIDL Генерируемый заголовок C++
interface nsISil {
  void twiddleSil();
};
/* начало интерфейса:    nsISil */
class nsISil {
 public:

  /* void twiddleSil (); */
  NS_IMETHOD TwiddleSil(void) = 0;
};

Если по какой то причине умолчальное название для метода или свойства не может быть использованно, например, если название конфликтует с виндовым макросом, то может быть использован модификатор binaryname(Название), который изменит конфликтное название в коде C++. Например:

Код XPIDL Генерируемый заголовок C++
interface nsINameConflicts {
  [binaryname(MessageMoz)] attribute AString message;
  [binaryname(PostMessageMoz)] void postMessage(in AString message);
};
/* начало интерфейса: nsINameConflicts */
class nsINameConflicts {
 public:

  /* [binaryname(MessageMoz)] attribute AString message; */
  NS_IMETHOD GetMessageMoz(nsAString& message) = 0;
  NS_IMETHOD SetMessageMoz(const nsAString& message) = 0;
  /* [binaryname(PostMessageMoz)] void postMessage(in AString message); */
  NS_IMETHOD PostMessageMoz(const nsAString& message) = 0;
};

Предоопределенные типы

XPIDL предоставляет несколько предопределенных типов. Но могут использоваться и нативные типы, хотя это ограничивает возможность скриптования.

Тип Соответствие в C++
void void
boolean PRBool
octet PRUint8
short PRInt16
long PRInt32
long long PRInt64
unsigned short PRUint16
unsigned long PRUint32
unsigned long long PRUint64
float float
double double
char char
wchar PRUnichar
string char*
wstring PRUnichar*

Использование нативных типов

XPIDL позволяет использовать нативные типы, указанные с помощью декларации native, которая работает аналогично конструкции typedef в C++.

Нативный тип может быть задан именем с помощью следующего синтаксиса:

native name(native_type);

Возможно определить и типы ссылок и указателей, комбинируя [ref] или [ptr] с native:

Код XPIDL Генерируемый для C++
[ref] native nsNativeFileRef(nsFileSpec);
[ptr] native nsNativeFilePtr(nsFileSpec);

interface foo {
  void openByRef(in nsNativeFileRef aFileSpecRef);
  void openByPtr(in nsNativeFilePtr aFileSpecPtr);
};
/* начало интерфейса:    foo */
class foo {
 public:

  /* void openByRef (in nsNativeFileRef aFileSpecRef); */
  NS_IMETHOD OpenByRef(nsFileSpec & aFileSpecRef) = 0;

  /* void openByPtr (in nsNativeFilePtr aFileSpecPtr); */
  NS_IMETHOD OpenByPtr(nsFileSpec * aFileSpecPtr) = 0;
};

Использование в вашем коде нативных типов может быть полезно для переносимости существующих интерфейсов. Однако, использование нативных типов в методе делает этот метод недоступным из скриптов.

#include

Если вы ссылаетесь на интерфейсы, описанные в других файлах, то должны подключать их следующим способом: #include "имяфайла.idl". В XPIDL конструкция #include включает указанный файл только единожды. Поэтому нет нужды защищать конструкцию #include с помощью ifdef, как это делается в случае препроцессора C.

Перечисления и константы

Перечисления в стиле C не поддерживаются, поскольку размер перечислений может зависеть от компилятора. Вместо этого XPIDL поддерживает определения констант, которые становятся доступными как в C++ так и в JavaScript. Константы должны иметь тип short или long и должны объявляться внутри описаний интерфейсов.

Константы других типов не поддерживаются, поскольку не имеют аналогов в других языках либо требуют значительных издержек по управлению памятью. Вместо определения "constant", не являющегося типа short или long, пишите метод, возвращающий нужное значение, или положите это значение в атрибут.

Код XPIDL Код C++
const short c1 = 1+1; enum { c1 = 2 };
const short c2 = c1 * 5; enum { c2 = 10 };
const long flag = 1 << 5; enum { flag = 32 };
const float invalid_constant = 6.0; Предупреждение: проигнорировано объявление константы 'invalid_constant', тип которой не был "short" или "long".

[Правила и синтаксис] [Устоявшаяся практика] [Ключевые слова]

1: "XP", конечно же, означает "cross-platform" (кросплатформеный).
2: Я хочу лучшего названия для этого.


Mike Shaver
Mike Ang
Mike McCabe

Перевод: Д. Скоробогатов (08.10.2009)
Оригинальный текст: IDL Author's Guide - Rules and Syntax

Биржа долевых инвестиций SIMEX.

Последнее редактирование: 2009-10-12 16:50:12

Метки материала: XPIDL, XPCOM, языки программирования, C++, язык описаниния интерфейсов, файлы интерфейсов, синтаксис, правила, language, Interface Description Language, interface, компонентная объектная модель, syntax, OMG IDL, IDL, Component Object Model, интерфейсы

Оставьте, пожалуйста, свой комментарий к публикации

Представиться как     Антибот:
   

Просьба не постить мусор. Если вы хотите потестить xBB, воспользуйтесь кнопкой предварительного просмотра на панели инструментов xBBEditor-а.


© 2007-2017, Дмитрий Скоробогатов.
Разрешается воспроизводить, распространять и/или изменять материалы сайта
в соответствии с условиями GNU Free Documentation License,
версии 1.2 или любой более поздней версии, опубликованной FSF,
если только иное не указано в самих материалах.