Таблица8
.1.
Ключевые слова IDL
abstract
enum
native
struct
any
factory
Object
supports
attribute
FALSE
octet
typedef
boolean
fixed
oneway
unsigned
case
float
out
union
char
in
raises
ValueBase
const
inout
readonly
valuetype
cell
interface
sequence
void
double
long
short
wchar
exception
module
string
Ключевые слова, перечисленные в табл. 8.1, представл я ют собой зарезервированные слова, используемые в CORBA-программах. Помимо определени я интерфейса функций дл я класса, я зык IDL используетс я дл я определени я отношений между к л ассами. IDL под д ерживает:
• типы, определенные пользователем;
• последовательности, определенные пользователе м;
• типы массивов;
• рекурсивные типы;
• семантику исключений;
• модули (по аналогии с пространствами имен);
• единичное и множественное наследование;
• поразрядные арифметические операторы.
Приведем IDL-определение для класса adding_machine из листинга 8.2:
interface adding_machine{
void add(in unsigned long X);
void subtract(in unsigned long X);
long result();
}
Это определение начинается с ключевого слова CORBA interface. Обратите внимание на то, что данное объявление интерфейса класса adding_machine не включает ни одной переменной, которая бы могла хранить результат выполнения операций сложения и вычитания. Методы add () и subtract () принимают в качестве параметра одно значение типа unsigned long. Объявление типа параметра сопровождается ключевым словом CORBA in, который говорит о том, что данный параметр является входным (mput). Это объявление класса хранится в отдельном исходном файле adding_machine.idl. Исходные файлы, содержащие ГОЬюпределения, должны иметь . idl-расширения. Прежде чем такой файл можно будет использовать, его необходимо преобразовать к С++чЈюрмату. Это преобразование можно выполнить с помощью препроцессора или отдельной программы. Все CORBA-реализации включают IDL-компиляторы. Существуют IDL-компиляторы лля языков С, Smalltalk, С++, Java и др. IDL-компилятор преобразует ГОЬюпределения в код соответствующего языка. В данном случае IDL-компилятор преобразует объявление интерфейса в легитимный C++-код. В зависимости от конкретной CORBA-реализации IDL-компилятор вызывается с использованием синтаксиса, который будет подобен слелующему:
idl adding_machine.idl
При выполнении этой команды создается файл, содержащий С++-код. Поскольку наше IDL-определение хранится в файле adding_machine. idl, MICO IDL-компилятор создаст файл adding_machine. h, который будет содержать несколько каркасных C++-классов и CORBA-типов данных. Базовые IDL-типы данных приведены в табл. 8.2.
Таблица 8.2. Базовые IDL -т ипы дан н ых
IDL-типы данных
Диапазон
Размер
long
1
>
_2»-2' 5 -
1
> 16 бит
0-2 v - 1
> 32 бит
IDL-типы данных
Диапазон
Размер
long
-2
31
- 2
31
-1
≥ 32 бит
short
-2
15
- 2
15
-1
≥ 16 бит
unsigned long
0 - 2
32
-1
≥ 32 бит
unsigned short
0-2
16
-1
≥ 16 бит
float
IEEE с обычной точностью
≥ 32 бит
double
IEEE с двойной точностью
≥ 64 бит
char
ISO
л
атинский-1
≥8 бит
string
ISO
л
атинский-1, за иск
л
ючением ASCII
NULL
Переменный
boolean
TRUE ИЛИ FALSE
Не определен
octet
0-255
≥8 бит
any
Произвольный тип, идентифицируемый динамически
Переменный
Даже после того как IDL-компилятор создаст из определения интерфейса С++-код, реализация методов интерфейсного класса остается все еще неопределенной. IDL-компилятор создает несколько С++-конструкций, которые предназначены для использования в качестве базовых классов. В листинге 8.3 показано два класса, сгенерированных MICO IDL-компилятором на основе файла adding_machine.idl .
// Листинг 8.3. Два класса, сгенерированные
// MICO IDL-компилятором из файла
// adding_machine.idl
class adding_machine : virtual public CORBA::Object{
public:
virtual ~adding_machine();
#ifdef HAVE_TYPEDEF_OVERLOAD
typedef adding_machine_ptr _ptr_type;
typedef adding_machine_var _var_type;
#endif
static adding_machine_ptr _narrow(CORBA::Object_ptr obj );
static adding_machine_ptr _narrow(CORBA::AbstractBase_ptr obj );
static adding_machine_ptr _duplicate(adding_machine_ptr _obj ){
CORBA::Object::_duplicate (_obj); return _obj;
}
static adding_machine_ptr _nil(){
return 0;
}
virtual void *_narrow_helper( const char *repoid );
static vector<CORBA::Narrow_proto> *_narrow_helpers;
static bool _narrow_helper2( CORBA::Object_ptr obj );
virtual void add( CORBA::ULong X ) = 0;
virtual void subtract( CORBA::ULong X ) = 0;
virtual CORBA::Long result() = 0;
protected:
adding_machine(){};
private:
adding_machine( const adding_machine& );
void operator=( const adding_machine& );
};
class adding_machine_stub : virtual public adding_machine{
public:
virtual ~adding_machine_stub();
void add( CORBA::ULong X );
void subtract( CORBA::ULong X ); CORBA::Long result();
private:
void operator=( const adding_machine_stub& );
};
Файл adding_machine.idl — это входные данные для компилятора, а файл adding_machine.h вместе с каркасны м и класса м и— результат его работы. Чтобы реализовать интерфейсы функций, объявленные в исходно м IDL-файле, разработчик использует наследование. Напри м ер, в листинге 8.4 представлен определенный пользователе м класс, который обеспечивает реализацию для одного из каркасных классов, созданных IDL-ко м пиляторо м.
// Листинг 8.4. Класс реализации структурных классов, // созданных IDL-компилятором
class adding_machine_impl : virtual public adding_machine_skel {
private:
CORBA::Long Result;