Если совокупность cpp- и hh-файлов на стороне клиента называют стабом, то их аналог на стороне сервера – скелетоном (skeleton). Задача, которую решает сгенерированный на стороне сервера код, это обеспечение основы для создания сервантов – классов, которые реализуют функциональность сервера приложений, а также выполнение вызовов методов этих сервантов по запросу клиентов. Как правило, размер сгенерированного кода на стороне сервера существенно меньше, чем на стороне клиента. В простейшем случае для одного интерфейса, объявленного в IDL-файле, генерируется всего один класс. Это не случайно – если стабы клиента, по сути, решают все проблемы взаимодействия клиентского приложения с CORBA, то скелет на стороне сервера – это только основа того, что должно быть написано разработчиком при создании сервера приложений.
В качестве примера используем то же самое IDL-объявление, что и раньше:
// IDL
interface MyInterface
{
void MyMethod(in long arg);
};
// C++
class MyInterface : ...
{
public:
…
virtual long MyMethod(long _arg) throw(CORBA::SystemException) = 0;
void _MyMethod(void* _obj, InBuffer& _isrtm,
static const char* _oper, VISReplyHandler& handler);
...
};
Для IDL-метода MyMethod в классе скелета сгенерированы два метода: чисто виртуальный метод MyMethod() и статический метод _MyMethod(). Действия, выполняемые методом _MyMethod(), теперь для вас уже, наверное, очевидны:
void _MyMethod(void* _obj, InBuffer& inBuf, OutBuffer& outBuf)
{
...
MyInterface* impl = (MyInterface*)_obj;
long arg;
inBuf >> arg;
long ret = impl->MyMethod(_local_arg);
outBuf << ret;
}
То, что настоящий метод MyMethod() объявлен как виртуальный, означает только одно: вы должны создать класс, производный от класса скелета, и в нем обеспечить реализацию этого метода, например:
class MyInterfaceImplementation : public MyInterface
{
virtual long MyMethod(long _arg) throw(CORBA::SystemException)
{
return _arg + 1;
}
};
Переменные типа MyInterfaceImplementation и будут называться сервантами.
Обратите внимание:если в IDL-декларации метода присутствует список исключительных ситуаций, то соответствующие C++-эквиваленты этих исключений будут добавлены в throw-список для вашего метода.
Существует еще один способ реализации сервента. Этот способ называется модель делегирования.