列集(Marshaling)
RCF決定哪個(gè)方向的參數(shù)被列集時(shí),是遵循C++慣例的。特別地,一個(gè)接口的所有的參數(shù)都是入?yún)ⅲ?/span>in parameter),所有的non-const引用參數(shù)都是in-out參數(shù),所有的返回值都是出參(out parameter)。但是也沒有強(qiáng)制規(guī)定一定要遵循這些in/out/inout慣例。
并不是C++里的所有東西都可以被安全地列集,這也限制了接口方法的參數(shù)類型。也就是說,指針和引用可以作為參數(shù);指針的引用不允許作為參數(shù);指針和引用不能作為返回值。
這也意味著如果一個(gè)接口的方法想要返回一個(gè)指針,比如一個(gè)多態(tài)指針,返回值就需要時(shí)一個(gè)像std::auto_ptr
<> 或者 boost::shared_ptr
<>的智能指針?;蛘咂渲幸粋€(gè)參數(shù)可以是一個(gè)智能指針的non-const引用。
序列化
Echo那個(gè)例子只序列化了std::
string對(duì)象,但它(RCF)在使用序列化的情況下幾乎可以發(fā)送所有的C++類和結(jié)構(gòu)。RCF擁有自己的序列化框架,名字就叫序列化框架(SF),同時(shí)它也支持Boost.Serialization
框架,這個(gè)框架是Boost庫的一部分。
一般說來,需要在將被序列化的類里面包含序列化代碼。如果你在接口有一個(gè)std::vector
<>參數(shù),你需要包含<SF/vector.hpp>或者<boost/serialization/vector.hpp>(或者同時(shí)包含兩者),對(duì)于其他的STL和Boost庫也是一樣。
在RCF接口中使用你自己的類,你需要一個(gè)自定義的序列化方法,在大多數(shù)情況下,這非常簡單。
#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;
//} 當(dāng)處理指向多態(tài)對(duì)象指針和循環(huán)指針的時(shí)候,序列化會(huì)變成一個(gè)很復(fù)雜的事情。SF
和Boost.Serialization
都能處理這些情況,但是用的是不同的方法,所以為了適應(yīng)兩種序列化系統(tǒng)需要寫不同的序列化代碼。下面的例子使用了SF
和Boost.Serialization
來發(fā)送多態(tài)對(duì)象。
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接口現(xiàn)在支持多繼承。不僅可以從別的接口繼承,還可以繼承自標(biāo)準(zhǔn)C++類。接口內(nèi)的方法可以用它們的分派ID和它們所屬的接口名來標(biāo)識(shí)。這樣的信息對(duì)于服務(wù)器端用來映射來自客戶端的調(diào)用到正確的服務(wù)器端綁定來說已經(jīng)足夠了。下面的例子示范了接口繼承:
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 &e = clientF;
e.func5();
}
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)
點(diǎn)擊舉報(bào)。