ZeroC ICE中的对象
在ZeroC Ice中定义了三种基本对象类型。
它们分别是IceProxy::Ice::Object(于Ice/Proxy.h),Ice::Object(于Ice/Object.h)和Ice::LocalObject(于Ice/LocalObject.h)。
这三种基本对象类型的基类都是Shared。Shared类的作用就是一个引用计数,利用引用计数管理内存,在c++11之前,相当于boost::shared_ptr的作用。在整个Ice项目中一切需要使用引用计数的类都继承自Shared。而上面定义的三个基本对象就是与Ice Object概念相关。
我们先来看一下关于Handle,指针管理的类。

Handlebase对指针进行简单的包装,包装了指针的最基本的操作,引用操作以及指针空判断。Handle和ProxyHandle继承自HandleBase,充当智能指针管理器,并要求被管理的指针的指向的对象的类型继承自Shared,即指针指向的对象是利用引用计数进行内存管理。Handle和ProxyHandle重载了构造以及赋值拷贝函数,完成指针传递过程中的自动引用计数。项目中使用指针管理器代替直接使用底层指针。指针的传递通过指针管理器完成,传递过程自动完成对指针指向的对象的引用计数。
现在就来看Handle和ProxyHandle的区别。Handle提供dynamicCast方法,而ProxyHandle提供checkedCast和uncheckedCast,以及upCast方法。
Handle提供的dynamicCast就如名字一样,只是简单地进行c++的dynamic_cast类型转换,因为它管理的指针的对象,就是native的c++继承类。
ProxyHandle的upCast直接向上转换成Shared。checkedCast和uncheckedCast是用来向下转换的。ProxyHandle用于管理Ice Object的代理指针,代理不是一种native的c++继承关系的类,因为一个Ice Object可能有多个接口(facets),而这个Ice Object可能有不只一种类型的服务实体提供服务,甚至实体之间没有接口的继承。这个Ice Object的代理注定不是一个由继承完成的类,而是一系列的接口代理端的类。所以ProxyHandle在进行向下类型转换的时候不能直接使用c++native的类型转换。实际上Ice也并对代理进行类型转换,那它做了什么?
看下面的实现:
//
// checkedCast and uncheckedCast functions without facet:
//
template<typename P> P
checkedCastImpl(const ::Ice::ObjectPrx& b, const ::Ice::Context& context)
{
P d = ;
if(b.get())
{
typedef typename P::element_type T; if(b->ice_isA(T::ice_staticId(), context))
{
d = new T;
d->_copyFrom(b);
}
}
return d;
} template<typename P> P
uncheckedCastImpl(const ::Ice::ObjectPrx& b)
{
P d = ;
if(b)
{
typedef typename P::element_type T; d = dynamic_cast<T*>(b.get());
if(!d)
{
d = new T;
d->_copyFrom(b);
}
}
return d;
}
checkedCastImpl和uncheckedCastImpl最后采取的行动是对向下的代理类型进行实例。不同于checkedCastImpl,uncheckedCastImpl允许你对代理进行简单的c++native向下(上)类型转换,因为你当前使用的接口(facet)代理可能与你想要转换的目标接口(facet)代理,这两个接口间存在继承关系。但是uncheckedCastImpl不会像checkedCastImpl那样马上发送一个ice_isA调用,去验证在远端的"Ice Object"是否支持你的代理转换后的接口。如果你不手动去调用ice_isA验证这个代理的接口的话,就不能知道远端的"Ice Object"是否支持你想要的接口,除非直到你调用一个接口方法后返回了异常,你才能知道远端的"Ice Object"不支持你的接口。
uncheckedCast只会从继承树的角度进行转换,同一继承树就直到转换,不同一继承树就创建新的代理实例。
checkedCast是从"Ice Object"的角度进行转换,只要远端"Ice Object"应答ice_isA成功,一律创建新的代理实例。
最典型的就是,我们要是使用Ice Object都必须通过代理。当我们通过Ice环境创建出一个代理,Ice环境总是返回一个最基本的接口代理ObjectPrx(就是ProxyHandle<::IceProxy::Ice::Object>)。这个最基本接口代理包含了几个最基本的接口方法,如ice_isA,ice_ids和ice_ping等。我们可以通过上面任意方法激活一个Ice Object。但我们需要使用我们自定义的接口时,我们就需要使用对应的接口代理,我们就需要转换接口代理的类型,尽管我们的接口代理继承自::IceProxy::Ice::Object,但是我们不要求ProxyHandle进行向下类型转换时,ProxyHandle就只能按我们希望的接口代理类型,新实例一个代理给我们。因为这个接口代理并没有实例,ProxyHandle根本不可能通过对::IceProxy::Ice::Object进行简单的向下类型转换而得到。
现在已经提到了::IceProxy::Ice::Object,那么它与::Ice::Object的关系就清楚了。::IceProxy::Ice::Object与::Ice::Object作为一个Ice Object的最小功能的两方面,一方面是我们使用的代理,另一方面是为我们提供的服务。::IceProxy::Ice::Object与::Ice::Object实现最小接口方法集包含如下:
const string object_all[] =
{
"ice_id",
"ice_ids",
"ice_isA",
"ice_ping"
};

左边为Ice Object使用的客户端(代理端),右边是服务端(servant)。作为最基本的对象的两面,它们已经实现了4个最基本的接口方法,ice_id,ice_ids,ice_isA以及ice_ping。服务端以_iceD_前缀对应接口方法的函数,是在_iceDispatch函数分派调用的分支入口。通过接口方法在两端的原型比较,有这些的规律。生成的代理端接口方法函数有一个依赖参数,类型是Context(,实质是一个字符串map或字典);生成的服务端接口方法函数也有一个依赖参数,类型是Current。Current包含了以下内容,Identity,facet,operation,mode,context,requestId以及EncodingVersion,这些就包含在协议的请求头中,详细请参看上一篇《ZeroC ICE的协议》。服务端解释出请求头后,分派到具体servant实体后,由servant实体的_iceDispatch进行分派,_iceD_X函数再从Incoming的inputStream反序列化出调用参数,最后调用接口方法的函数实现体进行处理。
所以有如下图

slice程序根据接口描述文件Module.ice分别在名字空间::IceProxy::Module和::Module下生成同名的接口类。它们分别继承名字空间::IceProxy::Ice和::Ice下的Object类。这两个同名的接口类为我们完成Ice远程调用的框架,通过实现体ConcreteIntfImpl覆盖多态方法,实现接口方法。
ZeroC ICE中的对象的更多相关文章
- ZeroC ICE中的对象模型和概念
Ice对象的模型和概念. Ice Object并非是我们的接口实现类的实例对象.我们的接口实现类的实例对象只是充当Ice Object的Servant的角色.一个Ice Object可以有众多Serv ...
- zeroc ice log4net 多进程log文件问题
使用zeroc ice 中的icebox 的时候多服务会有多个服务实例,每个实例都要写日志文件,所以要配置多个日志文件区分开来, 类似这样 orderservice_1_20160101.log ...
- ZeroC Ice 暂记
摘自: http://weibo.com/p/1001603869896789339575 原文地址: http://www.oschina.net/question/865233_242146 吴治 ...
- ZEROC ICE 跨平台间程序调用 java版
前言: 本来建博客是为了和大家分享一些前端的开发经验和心得呢,但是阴差阳错,第一篇技术博客确实关于跨平台,跨语言服务端调用的解决方案---ZEROC ICE. 最近一个项目涉及到java.python ...
- Zeroc Ice Slice语言使用 HelloWorld
Slice介绍 为了开发多语言支持的RPC服务,需要一种中立的新语言来定义这个服务接口,以便各个编程语言能够准确无误地理解和翻译接口,为此Ice设计了Slice语言.Ice开发的第一步 ...
- Zeroc Ice原理介绍
Ice介绍 Ice(Internet Communications Engine)是ZeroC公司的杰作,继承了CORBA的血统,是新一代的面向对象的分布式系统中间件.Ice是RPC通 ...
- ZeroC Ice Ice Registry实现负载均衡
Registry介绍 对于多个IceBox集群该怎么负载均衡?以服务注册表Registry为依托的Service Locator组件,以及依赖其而诞生的强大的分分布式框架-IceGri ...
- Ubuntu16.04下ZeroC ICE的安装与使用示例(Qt C++ 和 Java)
项目需求:在Ubuntu16.04系统下安装并使用ICEgrid 3.7进行c++和Java Springboot开发环境的通信,下面逐一介绍各个步骤的详解: 一:Ice Lib的安装 参考官网地址: ...
- 用Python开发Zeroc Ice应用
Zeroc Ice简介 Zeroc ICE(Internet Communications Engine ,互联网通信引擎)是目前功能比较强大和完善的RPC框架,支持跨平台.跨语言调用.它非常灵活 ...
随机推荐
- 刷14道leetcode的总结
引子 为什么我要刷leetcode?换工作?不是!那是?玩!巴菲特的双目标清单系统,基本方法是列两个清单,一个是职业生涯最重要的目标(不超过5个),另一个是比较重要的目标.对于比较重要的目标,要像躲避 ...
- electron开发环境搭建
开发环境 Node.js Vscode vscode安装Debugger for Chrome 创建开发目录(也是解决方案) 执行初始化命令,创建electronpicture工程,并添加main.j ...
- 03 python学习笔记-文件操作(三)
本文内容主要包括以下方面: 1. 文件操作基本认识2. 只读(r, rb)3. 只写(w, wb)4. 追加(a, ab)5. r+读写6. w+写读7. a+写读(追加写读)8. 文件的修改 一.文 ...
- 【Bug】解决 SpringBoot Artifact contains illegal characters 错误
解决 SpringBoot Artifact contains illegal characters错误 错误原因:Artifact包含非法字符(大写字母) 解决方法:将Artifact名称改成小写 ...
- iOS 应用签名原理&重签名
在苹果的日常开发中,真机测试与打包等很多流程都会牵扯到各种证书,CertificateSigningRequest,p12等.但是很多相应的开发者并不理解iOS App应用签名的原理和流程.今天着重讲 ...
- deepin15.7挂载/home到单独的分区:
1.首先打开Gpart分区编辑器,找一个空闲的分区,调整好分区大小,格式化成ext4格式. 具体步骤为首先unmount所用到的盘,然后右击该盘选择'format to ext4',最后点击apply ...
- vue引入css文件报错Unrecognised input
一个vue项目中用到了swiper插件,引入swiper.css时报错 显示引入的css文件Unrecognised input ,在文件的line4,column12 . 其实是引入位置不对,样式文 ...
- 面经-科大讯飞AI研究院
面试时间:2019.06.27 电话面试 面试岗位:计算机视觉算法工程师/一面 面试时长:45分钟 面试内容: 自我介绍 简历中选择一个项目介绍-视频召回 问及项目中的语音.人脸.标题.模态缺失相关细 ...
- (大模拟紫题) Luogu P1953 易语言
原题链接:P1953 易语言 (我最近怎么总在做大模拟大搜索题) 分别处理两种情况. 如果只有一个1或0 直接设一个cnt为这个值,每次输入一个新名字之后把数字替换成cnt,最后cnt++即可. 注意 ...
- CSPS模拟 58
爆炸 没算内存见祖宗 为什么偏偏这次卡内存我没算 T1 HashMap各种水 T2 智障背包!但是卡内存! T3 Dashspeed 考试用点分治+线段树水到了80 实际上是个没见过的套路题 在之前的 ...