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框架,支持跨平台.跨语言调用.它非常灵活 ...
随机推荐
- vue 代码迁移的坑
由于开发需要,开发过程中总会遇到由于代码调试.svn/git上传等过程中,总会出现代码迁移文件的需求,很多时候,迁移过后总会出现一些大大小小的问题, 首先,需要迁移文件内有没有系统自动隐藏的文件(例如 ...
- 五分钟后,你将学会在SpringBoot项目中如何集成CAT调用链
买买买结算系统 一年一度的双十一购物狂欢节就要到了,又到剁手党们开始表演的时刻了.当我们把种草很久的商品放入购物车以后,点击"结算"按钮时,就来到了买买买必不可少的结算页面了.让我 ...
- 一次PHP代码上线遇到的问题
exception ‘CDbException’ with message ‘The table “pms_goods” for active record class “PmsGoods” cann ...
- 变量 + 数据类型(数字 + 字符串)(day03整理)
目录 一.上节课回顾 四 编程语言分类 (一) 机器语言 (二)汇编语言 (三) 高级语言 (四) 网络瓶颈效应 五.执行python程序两种方式 (一) 交互式(jupytre) (二) 命令行式( ...
- unity 开启外部摄像头
在unity中建立一个image作为摄像头显示画面,然后通过命令render到image上即可. public WebCamTexture webTex; public string deviceNa ...
- python之ORM(对象关系映射)
实现了数据模型与数据库的解耦,通过简单的配置就可以轻松更换数据库,而不需要更改代码.orm操作本质上会根据对接的数据库引擎,翻译成对应的sql语句.所有使用Django开发的项目无需关心程序底层使用的 ...
- 深入理解大数据架构之——Lambda架构
目录 传统系统的问题 Lambda架构简介 Lambda架构关键特性 数据系统的本质 Lambda的三层架构 Lambda架构组件选型 总结 原文链接:https://jiang-hao.com/ar ...
- Java内存模型相关原则详解
在<Java内存模型(JMM)详解>一文中我们已经讲到了Java内存模型的基本结构以及相关操作和规则.而Java内存模型又是围绕着在并发过程中如何处理原子性.可见性以及有序性这三个特征来构 ...
- 【C#多线程】2.线程池简述+两种传统的异步模式
线程池简述+两种传统的异步编程模式 1.线程池简述 首先我们要明确一点,编程中讲的线程与平时我们形容CPU几核几线程中的线程是不一样的,CPU线程是指逻辑处理器,比如4核8线程,讲的是这个cpu有8个 ...
- Web for pentester_writeup之LDAP attacks篇
Web for pentester_writeup之LDAP attacks篇 LDAP attacks(LDAP 攻击) LDAP是轻量目录访问协议,英文全称是Lightweight Directo ...