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

翻译 2008年05月18日 14:01:00

列集(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>(或者同时包含两者),对于其他的STLBoost库也是一样。

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 &baseconst 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();
}

相关文章推荐

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

可扩展性 传输 对于前一个版本的RCF,一个(应得的)批评是关于它和TCP协议过度紧密的关系。现在RCF采用了传输无关的设计,并且对于初用者,可以使用它支持的TCP和UDP协议。更重要的是,它...

Boost.Asio的使用技巧

基本概念 Asio proactor I/O服务 work类run() vs poll()stop()post() vs dispatch()buffer类缓冲区管理 I/O对象 ...
  • educast
  • educast
  • 2013年10月27日 22:14
  • 10652

OTL sqlite

我用的是 :OTL 4.0, Example 277 (Simple Insert/Select/Update) 源码地址: http://otl.sourceforge.net/otl4_ex27...

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

RCF—用于C++的进程间通讯   导言 RCF(Remote Call Framework,远程调用框架)是一个C++的框架。这个框...
  • ilvu999
  • ilvu999
  • 2012年10月20日 22:51
  • 1858

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

导言 RCF(Remote Call Framework,远程调用框架)是一个C++的框架。这个框架用来为实现C++程序进程间调用提供一个简单和一致(consistent)的方法。这个框架基于强...

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

过滤器(Filters) RCF通过过滤器的概念来支持对消息的压缩和加密。过滤器需要同时应用于服务器端和客户端。也可以被应用于传输层,例如应用SSL过滤器到向TCP这样基于流的传输;或者应用于独立的...

Linux进程间通讯—旗语

/* * 生产者/消费者模型 * 给定仓库容积(N) * 生成者生成的产品入库 * 消费者从仓库中取出产品消费 * 仓库满了时生产者不能继续生成 * 仓库为空时消费者不能继续消费 * 对...

进程间通讯————消息队列

Linux支持system V 提供的进程间通信机制:消息队列、信号(semaphores)和共享内存。称为system V的IPC对象,可以通过系统调用(system call)对对象的创建者设置这...

Java—进程间通讯的有几种方法

进程间通信的方法主要有以下几种:   (1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。   (2)命名管道(named pipe):...

Windows上C++使用共享内存进行进程间通讯

共享内存 (也叫内存映射文件) 主要是通过映射机制实现的 , Windows 下进程的地址空间在逻辑上是相互隔离的 , 但在物理上却是重叠的 ; 所谓的重叠是指同一块内存区域可能被多个进程同时使用 ,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:RCF—用于C++的进程间通讯(2)
举报原因:
原因补充:

(最多只允许输入30个字)