omniORB笔记

omniORB笔记1
2007-08-30 16:33

资料来源:omniORB4.07库自带
我的英文很差,要翻译和理解doc下一堆英文很有挑战性。

一些简单说明:
omniORB是CORBA(公用对象代理体系架构)的一种开发库,主要适用C++和python。CORBA
实现了异构系统的异种语言软体合并、协作。
CORBA的大体实现方式:使用IDL实现与其它编程语言的映射;客户端与服务端使用GIOP
(主要是IIOP)协议进行通讯;客户端使用一种映射语言编写stub(桩)代码,使用对象引用、
服务端使用同种或异种映射语言编写skelecton(骨架)代码,真正实现服务;上述二者通过
CORBA服务进行通讯。

实例分析(echo):
Echo.idl
interface Echo {
string echoString(in string mesg);
};

使用omniidl.exe编译idl文件,生成c++桩文件。如下:
omniidl -bcxx echo.idl

按照c++的语法,会生成6个类:Echo_Helper、Echo、_objref_Echo
和_pof_Echo、_impl_Echo、POA_Echo。
还有4个重要的typedef:
typedef _objref_Echo* Echo_ptr;
typedef Echo_ptr EchoRef;
typedef _CORBA_ObjRef_Var<_objref_Echo, Echo_Helper> Echo_var;
typedef _CORBA_ObjRef_OUT_arg<_objref_Echo,Echo_Helper > Echo_out;

可以认为_objref_Echo* 、Echo_ptr、EchoRef还有Echo_var是相同的东西。
但是使用的时候,使用Echo_ptr和Echo_var居多,注意,不允许使用非引用(可以
看作C++指针)方式访问CORBA成员。
我是这样理解的,前三个类为客户端的桩,后三个类为服务端的桩,很可能不对,不过
暂时还不怎么明白。
先看一下前三个类定义的代码:
class Echo_Helper {
public:
   typedef Echo_ptr _ptr_type;

   static _ptr_type _nil();
   static _CORBA_Boolean is_nil(_ptr_type);
   static void release(_ptr_type);
   static void duplicate(_ptr_type);
   static void marshalObjRef(_ptr_type, cdrStream&);
   static _ptr_type unmarshalObjRef(cdrStream&);
};

class Echo {
public:
   // Declarations for this interface type.
   typedef Echo_ptr _ptr_type;
   typedef Echo_var _var_type;

   static _ptr_type _duplicate(_ptr_type);
   static _ptr_type _narrow(CORBA::Object_ptr);
   static _ptr_type _unchecked_narrow(CORBA::Object_ptr);
   static _ptr_type _nil();

   static inline void _marshalObjRef(_ptr_type, cdrStream&);

   static inline _ptr_type _unmarshalObjRef(cdrStream& s) {
     omniObjRef* o = omniObjRef::_unMarshal(_PD_repoId,s);
     if (o)
       return (_ptr_type) o->_ptrToObjRef(_PD_repoId);
     else
       return _nil();
   }

   static _core_attr const char* _PD_repoId;
};

class _objref_Echo :
   public virtual CORBA::Object, public virtual omniObjRef
{
public:
   char* echoString(const char* mesg);

   inline _objref_Echo()   { _PR_setobj(0); }   // nil
   _objref_Echo(omniIOR*, omniIdentity*);

protected:
   virtual ~_objref_Echo();

private:
   virtual void* _ptrToObjRef(const char*);

   _objref_Echo(const _objref_Echo&);
   _objref_Echo& operator = (const _objref_Echo&);
   // not implemented

   friend class Echo;
};

_objref_Echo继承自CORBA::Object(CORBA总基类),因此可以看作Echo_ptr继承于
CORBA::Object_ptr,不过其实是不存在这种关系的。echoString是_objref_Echo的成员,
Echo作为_objref_Echo的友元,造成二者的紧密结合。
这里先解释一下一般OCRBA类的三个重要静态函数_duplicate、_nil、_narrow,他们的
参数不同,但返回值是一致的Echo_ptr。简而言之,_duplicate返回复制的对象引用、
_nil返回0引用,CORBA里的0引用不一定是0、_narrow返回向下转型引用,失败返回0
引用,类似于c++的dynamic_case。

我们获取引用的方法不直接通过_objref_Echo,而是调Echo的静态方法,以加以保护,
这也是Echo存在的真正原因;另外_duplicate、_narrow返回的引用会增加对象的引用
计数,必须通过release全局函数进行释放,这样造成了Echo_Helper的产生,注意
typedef _CORBA_ObjRef_Var<_objref_Echo, Echo_Helper> Echo_var,我之所以说
Echo_var与Echo_ptr是同样的东西,从这个typedef可以看出,_objref_Echo以Echo_Helper
作为辅助将对象进行了托管,因此使用Echo_var时,无需release。

在看一下后三个类的定义:
class _pof_Echo : public _OMNI_NS(proxyObjectFactory) {
public:
   inline _pof_Echo() : _OMNI_NS(proxyObjectFactory)(Echo::_PD_repoId) {}
   virtual ~_pof_Echo();

   virtual omniObjRef* newObjRef(omniIOR*,omniIdentity*);
   virtual _CORBA_Boolean is_a(const char*) const;
};

class _impl_Echo :
   public virtual omniServant
{
public:
   virtual ~_impl_Echo();

   virtual char* echoString(const char* mesg) = 0;
  
public:   // Really protected, workaround for xlC
   virtual _CORBA_Boolean _dispatch(omniCallHandle&);

private:
   virtual void* _ptrToInterface(const char*);
   virtual const char* _mostDerivedRepoId();
};

class POA_Echo :
   public virtual _impl_Echo,
   public virtual PortableServer::ServantBase
{
public:
   virtual ~POA_Echo();

   inline ::Echo_ptr _this() {
     return (::Echo_ptr) _do_this(::Echo::_PD_repoId);
   }
};
我不大理解_pof_Echo,不过看样子应该是一种通过ID的认证方式。_impl_Echo继承自
omniServant,实现了服务端的桩。不过,要获得他的引用则需通过其派生类POA_Echo。
POA(可移植对象适配器)。

我们可以编写真正的服务端代码是POA_Echo的子类,下面是一个本地化的例子:
1、local
class Echo_i : public POA_Echo,
         public PortableServer::RefCountServantBase
{
public:
         inline Echo_i() {}
         virtual ~Echo_i() {}
         virtual char* echoString(const char* mesg);
};
char* Echo_i::echoString(const char* mesg)
{
         return CORBA::string_dup(mesg);
}

static void hello(Echo_ptr e)
{
         if( CORBA::is_nil(e) ) {
                 cerr << "hello: The object reference is nil!/n" << endl;
                 return;
         }
         CORBA::String_var src = (const char*) "Hello!";
         CORBA::String_var dest = e->echoString(src);
         cout << "I said, /"" << (char*)src << "/"." << endl
                 << "The Echo object replied, /"" << (char*)dest <<"/"." << endl;
}

int main(int argc, char** argv)
{
         try {
                 CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
                 CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
                 PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);
                 Echo_i* myecho = new Echo_i();
                 PortableServer::ObjectId_var myechoid = poa->activate_object(myecho);
                 Echo_var myechoref = myecho->_this();
                 myecho->_remove_ref();
                 PortableServer::POAManager_var pman = poa->the_POAManager();
                 pman->activate();
                 hello(myechoref);
                 orb->destroy();
         }      
         catch(...) {
                 cerr << "Caught unknown exception." << endl;
         }

         return 0;
}
这是src里的源码,不过debug的时候还是产生了异常,异常出在hello函数退出的
时候,堆内存的释放出了问题,先不管了。release没有问题,下边的程序也一样。

2、使用IOR(对象字符串域名)

server:
class Echo_i : public POA_Echo,
         public PortableServer::RefCountServantBase
{
public:
         inline Echo_i() {}
         virtual ~Echo_i() {}
         virtual char* echoString(const char* mesg);
};
char* Echo_i::echoString(const char* mesg)
{
         cerr << "Upcall " << mesg << endl;
         return CORBA::string_dup(mesg);
}
int main(int argc, char** argv)
{
         try {
                 CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
                 CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
                 PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);
                 Echo_i* myecho = new Echo_i();
                 PortableServer::ObjectId_var myechoid = poa->activate_object(myecho);
                 obj = myecho->_this();
                 CORBA::String_var sior(orb->object_to_string(obj));
                 cerr << "'" << (char*)sior << "'" << endl;                
                 outfile.flush();
                 myecho->_remove_ref();
                 PortableServer::POAManager_var pman = poa->the_POAManager();
                 pman->activate();
                 orb->run();
         }        
         catch(...) {
                 cerr << "Caught unknown exception." << endl;
         }
         return 0;
}

client:
static void hello(Echo_ptr e)
{
         CORBA::String_var src = (const char*) "Hello!";
         CORBA::String_var dest = e->echoString(src);
         cerr << "I said, /"" << (char*)src << "/"." << endl
                 << "The Echo object replied, /"" << (char*)dest <<"/"." << endl;
}
int main(int argc, char** argv)
{
         try {
                 CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
                 if( argc != 2 ) {
                         cerr << "usage:   eg2_clt <object reference>" << endl;
                         return 1;
                 }
                 CORBA::Object_var obj = orb->string_to_object(argv[1]);
                 Echo_var echoref = Echo::_narrow(obj);
                 if( CORBA::is_nil(echoref) ) {
                         cerr << "Can't narrow reference to type Echo (or it was nil)." << endl;
                         return 1;
                 }
                 for (CORBA::ULong count=0; count<10; count++)
                         hello(echoref);

                 orb->destroy();
         }      
         catch(...) {
                 cerr << "Caught unknown exception." << endl;
         }
         return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值