在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中的对象的更多相关文章

  1. ZeroC ICE中的对象模型和概念

    Ice对象的模型和概念. Ice Object并非是我们的接口实现类的实例对象.我们的接口实现类的实例对象只是充当Ice Object的Servant的角色.一个Ice Object可以有众多Serv ...

  2. zeroc ice log4net 多进程log文件问题

    使用zeroc ice 中的icebox 的时候多服务会有多个服务实例,每个实例都要写日志文件,所以要配置多个日志文件区分开来, 类似这样  orderservice_1_20160101.log   ...

  3. ZeroC Ice 暂记

    摘自: http://weibo.com/p/1001603869896789339575 原文地址: http://www.oschina.net/question/865233_242146 吴治 ...

  4. ZEROC ICE 跨平台间程序调用 java版

    前言: 本来建博客是为了和大家分享一些前端的开发经验和心得呢,但是阴差阳错,第一篇技术博客确实关于跨平台,跨语言服务端调用的解决方案---ZEROC ICE. 最近一个项目涉及到java.python ...

  5. Zeroc Ice Slice语言使用 HelloWorld

    Slice介绍         为了开发多语言支持的RPC服务,需要一种中立的新语言来定义这个服务接口,以便各个编程语言能够准确无误地理解和翻译接口,为此Ice设计了Slice语言.Ice开发的第一步 ...

  6. Zeroc Ice原理介绍

    Ice介绍         Ice(Internet Communications Engine)是ZeroC公司的杰作,继承了CORBA的血统,是新一代的面向对象的分布式系统中间件.Ice是RPC通 ...

  7. ZeroC Ice Ice Registry实现负载均衡

    Registry介绍         对于多个IceBox集群该怎么负载均衡?以服务注册表Registry为依托的Service Locator组件,以及依赖其而诞生的强大的分分布式框架-IceGri ...

  8. Ubuntu16.04下ZeroC ICE的安装与使用示例(Qt C++ 和 Java)

    项目需求:在Ubuntu16.04系统下安装并使用ICEgrid 3.7进行c++和Java Springboot开发环境的通信,下面逐一介绍各个步骤的详解: 一:Ice Lib的安装 参考官网地址: ...

  9. 用Python开发Zeroc Ice应用

    Zeroc Ice简介   Zeroc ICE(Internet Communications Engine ,互联网通信引擎)是目前功能比较强大和完善的RPC框架,支持跨平台.跨语言调用.它非常灵活 ...

随机推荐

  1. 13.Linux文件查找-find命令

    find 命令的基本语法如下: 命令 路径 选项 表达式 动作 find [path...] [options] [expression] [action] 查找 地区 妹纸 18-25岁 约? (1 ...

  2. 第一章、Python环境搭建

    一.安装Python解释器 Windows下   Python开发环境搭建 1.官网下载: https://www.python.org/downloads/ 2.选择对应的版本 3.双击运行 4.选 ...

  3. < Window10更新后VWwareWorkstationPro无法运行(显示更新至新版本) >

    < Window10更新后VWwareWorkstationPro无法运行(显示更新至新版本) > 问题描述 我的Win10在国庆节后更新了微软发布的新补丁,由于当前正在上操作系统课,用到 ...

  4. Apollo学习笔记(一):canbus模块与车辆底盘之间的CAN数据传输过程

    Apollo学习笔记(一):canbus模块与车辆底盘之间的CAN数据传输过程 博主现在从车载自组网信道分配和多跳路由转向了自动驾驶,没啥经验,想快些做出来个Demo还是得站在巨人的肩膀上才行,我选择 ...

  5. $.ajax.html

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link rel= ...

  6. SQL查询小案例

    这是一篇自学MySQL的小案例,下面是部分数据信息:goods表 1.查询cate_name为‘超级本’的商品名称.价格 SELECT `name`, priceFROM goodsWHERE cat ...

  7. sqlite复制表

    (1)复制表,并把原表的 所有记录都复制到新表里. CREATE TABLE newTb AS SELECT * FROM oldTb (2)只复制表结构,不复制数据到新表里. 注:该语句无法复制关键 ...

  8. python3 range 倒序

    话不多说上代码,要求简单,从100到1遍历操作. //第三个参数表示的是100所有进行的操作,每次加上-1,直到0 for i in range(100,0,-1): print(i)

  9. ArcGIS Engine制作DIY地图工具

    本节将向你介绍,利用ToolStrip制作自定义GIS工具条. 步骤如下: ①向ToolStrip中添加一个Button ②向该Button的lmg属性添加图片素材,并将Button的图片比例(Ima ...

  10. oracle数据库锁表,什么SQL引起了锁表?ORACLE解锁的方法

    --查询数据库锁表记录 select sess.sid, sess.serial#, lo.oracle_username, lo.os_user_name, ao.object_name, lo.l ...