RCF—用于C++的进程间通讯(2)

列集(Marshaling)

RCF决定哪个方向的参数被列集时,是遵循C++惯例的。特别地,一个接口的所有的参数都是入参(in parameter),所有的non-const引用参数都是in-out参数,所有的返回值都是出参(out parameter)。但是也没有强制规定一定要遵循这些in/out/inout惯例。

并不是C++里的所有东西都可以被安全地列集,这也限制了接口方法的参数类型。也就是说,指针和引用可以作为参数;指针的引用不允许作为参数;指针和引用不能作为返回值。

这也意味着如果一个接口的方法想要返回一个指针,比如一个多态指针,返回值就需要时一个像 std::auto_ptr <>   或者   boost::shared_ptr <> 的智能指针。或者其中一个参数可以是一个智能指针的 non-const 引用。

序列化

Echo那个例子只序列化了std::string对象,但它(RCF)在使用序列化的情况下几乎可以发送所有的C++类和结构。RCF拥有自己的序列化框架,名字就叫序列化框架(SF),同时它也支持Boost.Serialization框架,这个框架是Boost库的一部分。

一般说来,需要在将被序列化的类里面包含序列化代码。如果你在接口有一个std::vector<>参数,你需要包含<SF/vector.hpp>或者<boost/serialization/vector.hpp>(或者同时包含两者),对于其他的STL和Boost库也是一样。

RCF 接口中使用你自己的类,你需要一个自定义的序列化方法,在大多数情况下,这非常简单。
#include  < boost / serialization / string .hpp >

#include 
< boost / serialization / map.hpp >
#include 
< boost / serialization / vector.hpp >

#include 
< SF / string .hpp >
#include 
< SF / map.hpp >
#include 
< SF / vector.hpp >

struct  X
{
    
int myInteger;
    std::
string myString;
    std::map
<
        std::
string,
        std::map
<int,std::vector<int> > > myMap;
}
;

//  this serialization function
//  will work as is with both SF and B.S.

template
< typename Archive >
void  serialize(Archive  & ar, X  & x)
{
    ar 
& x.myInteger & x.myString & x.myMap;
}


//  if you need to distinguish between SF and B.S. serialization,
//  specialize the SF serialization function:
// void serialize(SF::Archive &ar, X &x)
// {
//     ar & myInteger & myString & myMap;
// }

当处理指向多态对象指针和循环指针的时候,序列化会变成一个很复杂的事情。SFBoost.Serialization都能处理这些情况,但是用的是不同的方法,所以为了适应两种序列化系统需要写不同的序列化代码。下面的例子使用了SFBoost.Serialization来发送多态对象。

class  Base
{
    
// some members here
    
// ...
}
;

typedef boost::shared_ptr
< Base >  BasePtr;

class  Derived1 :  public  Base
{
    
// some members here
    
// ...
}
;

class  Derived2 :  public  Base
{
    
// some members here
    
// ...
}
;

template
< typename Archive >
void  serialize(Archive  & ar, Base  & base const  unsigned  int )
{
    
// ...
}


template
< typename Archive >
void  serialize(Archive  & ar, Derived1  & derived1,  const  unsigned  int )
{
    
// valid for both SF and B.S.
    serializeParent<Base>(derived1);

    
// ...
}


template
< typename Archive >
void  serialize(Archive  & ar, Derived2  & derived2,  const  unsigned  int )
{
    
// valid for both SF and B.S.
    serializeParent<Base>(derived1);

    
// ...
}


//  Boost type registration, needed on both server and client
BOOST_CLASS_EXPORT_GUID(Derived1,  " Derived1 " )
BOOST_CLASS_EXPORT_GUID(Derived2, 
" Derived2 " )

RCF_BEGIN(I_PolymorphicArgTest, 
"" )
    RCF_METHOD_R1(std::
string , typeOf, BasePtr)
RCF_END(I_PolymorphicArgTest)

class  PolymorphicArgTest
{
public:
    std::
string typeOf(BasePtr basePtr)
    
{
        
return typeid(*basePtr).name();
    }

}
;

{
    
// SF type registration, needed on both server and client
    SF::registerType<Derived1>("Derived1");
    SF::registerType
<Derived2>("Derived2");

    RcfClient
<I_PolymorphicArgTest> client(endpoint);

    
// SF serialization (default)
    client.getClientStub().setSerializationProtocol(RCF::SfBinary);
    std::
string typeBase = client.typeOf( BasePtr(new Base()) );
    std::
string typeDerived1 = client.typeOf( BasePtr(new Derived1()) );
    std::
string typeDerived2 = client.typeOf( BasePtr(new Derived2()) );

    
// Boost serialization
    client.getClientStub().setSerializationProtocol(RCF::BsBinary);
    typeDerived2 
= client.typeOf( BasePtr(new Derived2()) );
}

继承(Inheritance)

RCF接口现在支持多继承。不仅可以从别的接口继承,还可以继承自标准C++类。接口内的方法可以用它们的分派ID和它们所属的接口名来标识。这样的信息对于服务器端用来映射来自客户端的调用到正确的服务器端绑定来说已经足够了。下面的例子示范了接口继承:

RCF_BEGIN(I_A,  " I_A " )
    RCF_METHOD_V0(
void , func1)
RCF_END(I_Base)

RCF_BEGIN(I_B, 
" I_B " )
    RCF_METHOD_V0(
void , func2)
RCF_END(I_Base)

//  derives from I_A

RCF_BEGIN_INHERITED(I_C, 
" I_C " , I_A)
    RCF_METHOD_V0(
void , func3)
RCF_END(I_Base)

//  derives from I_A and I_B

RCF_BEGIN_INHERITED_2(I_D, 
" I_D " , I_A, I_B)
    RCF_METHOD_V0(
void , func4)
RCF_END(I_Base)

class  I_E
{
public:
    
virtual void func5() = 0;
}
;

//  derives from abstract base class I_E

RCF_BEGIN_INHERITED(I_F, 
" I_F " , I_E)
    RCF_METHOD_V0(
void , func5)
RCF_END(I_Base)

{
    RcfClient
<I_C> clientC(endpoint);
    clientC.func3();
    clientC.func1();

    RcfClient
<I_D> clientD(endpoint);
    clientD.func4();
    clientD.func2();
    clientD.func1();

    RcfClient
<I_F> clientF(endpoint);
    I_E 
&= clientF;
    e.func5();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值