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框架,支持跨平台.跨语言调用.它非常灵活 ...
随机推荐
- 我的Python学习方向-前端辅助-后端框架django学习-浅谈(一)
初始python,很直观的感受是编译格式多样,代码简介易懂 作为一门通用编程语言,python能编写多种用途的编程语言,当然对于我目前,我的方向便是借助其前端编辑器,实现后台框架的连接学习 1.首先便 ...
- springboot 打jar包时分离配置文件
修改pom.xml文件 <build> <resources> <resource> <directory>src/main/resources< ...
- label 标签的 for 属相
我的github iSAM2016 一开始学html 标签的时候,知道有label 这个标签的,但是并没有注意到他的for 属性的作用,看一下MDN的介绍 for 可标记的 form相关元素的ID,在 ...
- ArangoDB数据导入
目录 arangoimp方法 参数解析 实例展示 python方法 单条导入 批量导入 1.arangoimp方法 参数解析 全局配置部分(Global configuration) --backsl ...
- SpringBoot是如何启动的?
本文是通过查看SpringBoot源码整理出来的SpringBoot大致启动流程,整体大方向是以简单为出发点,不说太多复杂的东西,内部实现细节本文不深扣因为每个人的思路.理解都不一样,我个人看的理解跟 ...
- 百度ERNIE 2.0强势发布!16项中英文任务表现超越BERT和XLNet
2019年3月,百度正式发布NLP模型ERNIE,其在中文任务中全面超越BERT一度引发业界广泛关注和探讨. 今天,经过短短几个月时间,百度ERNIE再升级.发布持续学习的语义理解框架ERNIE 2. ...
- 【xinsir】分享一个查找文件的脚手架
program.command('find <name>').action(name => { if (name) { inquirer .prompt([ { type: 'inp ...
- 防抖(debounce)和 节流(throttling)
防抖(debounce)和 节流(throttling) 1.防抖和节流出现的原因 防抖和节流是针对响应跟不上触发频率这类问题的两种解决方案. 在给DOM绑定事件时,有些事件我们是无法控制触发频率的. ...
- python基础-列表List及内置方法
数据类型之列表-List 用途:用于存一个或多个不同类型的值 定义:通过中括号存值,每个值之间通过逗号进行分隔 l1 = [1,'a',3,'b'] 特性:有序.可变.存多个值的数据类型 常用方法: ...
- (大模拟紫题) Luogu P1953 易语言
原题链接:P1953 易语言 (我最近怎么总在做大模拟大搜索题) 分别处理两种情况. 如果只有一个1或0 直接设一个cnt为这个值,每次输入一个新名字之后把数字替换成cnt,最后cnt++即可. 注意 ...