(计算机软件与理论专业论文)基于组件技术的蓝牙服务器的设计与实现.pdf_第1页
(计算机软件与理论专业论文)基于组件技术的蓝牙服务器的设计与实现.pdf_第2页
(计算机软件与理论专业论文)基于组件技术的蓝牙服务器的设计与实现.pdf_第3页
(计算机软件与理论专业论文)基于组件技术的蓝牙服务器的设计与实现.pdf_第4页
(计算机软件与理论专业论文)基于组件技术的蓝牙服务器的设计与实现.pdf_第5页
已阅读5页,还剩74页未读 继续免费阅读

(计算机软件与理论专业论文)基于组件技术的蓝牙服务器的设计与实现.pdf.pdf 免费下载

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

中文摘要 中文摘要 摘要:随着软件技术的发展,静态开发模式已经不能满足需求。以组件的形式开 发出来的软件具有结构清晰、易于定制、便于动态扩展等特点,在臀i n d o w s 平台 上已经得到了广泛的应用。本文通过活动模版库技术将组件弓f 入到蓝牙软件 b 1 u e s o l e i l 服务器端的开发过程之中,并在此基础上实现了一个动态链接库处理 与组件的通信,客户端和第三方软件通过引用该d l l 就能调用组件提供的接口函 数,简化了开发流程。 本文对蓝牙协议栈进行了分析,介绍了组件的桷关技术,给出了软件的设计 方案和系统结构。详细讨论了各个功能模块,涉及应用协议s d k ,c o m 服务器,c o m 客户端,用户操作界面等。通过采用外壳扩展技术把用户操作嵌入到系统进程之 中,调用系统本身提供的功能、界面,提商了软件的易用性。 测试是软件开发的重要环节,本文以蓝牙文件传输应用为例,介绍一致性测 试操作流程。此外还开发出了针对该服务器的自动化测试工具,通过它可对软件 进行性能、互通性和鲁棒性测试。 关键词:蓝牙;组件对象模型( c o m ) ;活动模板库;自动化测试 分类号:t p 3 1 1 5 2 a b s n t a c t a b s t r a c t a b s t r a c t :w i t hm er a p i da d v a n c e so fs o 鼢黜妇e l o p f n e 吐s 碰cp a t t e n lo f d e v c l o p 蚰曲t h a sb e e nl h l a :b l et om e c tm ed e m 卸d s o r w a r ed e v c l o p c d 纽如ef o 肋o f c o m p o n c i l th a sm a n ya d v a i l t a g 骼,s i l c ha sd e a r 咖c h 黼,e 鹤yt ob ec l l s t o m i z e da n d f a c i k t a l ef b rd y n a i | l i ce x p 8 1 1 s i o 玛s oi th 私b e 衄w i d l yl l s e d 妇w i n d o 、v sp l a t 砌翘t 1 1 i s p a p 盯i 苴l t r o d u c e sc o m p o n 饥tc o n c e p tt os o f 啊a r ed e v d o p i n e n tp m c 髓sw i t ha r l t e c h n o l o g 冀a l 订i n 审l 锄e n tad l l t oh a n d l em ec o m m u n i c a t i o n b 嘲m 雕l e n ts e f y 盱 锄dd i e n t s ,a l lt h o s eh e i ps i n l p l 毋t h ed e v d o p m 鼽tp r o c 韶sal o t h lt l l 至sp a p b l u e t o o 斑p r 0 1 o c o ls 协呔i s 觚冯枷,i ta 】s oi n t r c l d u c 睇m e 翻a t e d t e c i l l l o l o g yo f m p o n e n ta n ds h o w s1 1 1 ed e s i 伊o ft h i 8s o n w a f ea n di t ss y s t e m a r c h “e c t u f e 越l 触l c t i o l lm o d m 酷羽ed i s c 璐s 。di nd e 晡li n d l l d i d gp r o f i l es d i ( ,c o m s e c o mc l i e n g u i ,e t c 。w e 鼬b c du s e ro p 咖i o n i n t os y s t 锄p r o c e s s b y t 幽n g s h d l t e c h n o l q ;y 勰dc a l l i n gs y s t e m 龟n c t i o n s ,t l l i sa :i s oi m p r o v 部m ea c 瞄s i b i l i t yo f s o n w a i e t b t i n gi s 觚i i n p o r t a n tp a ni l ld e v e l 叩p i n g f h a r 舔w eu f 肿p r o 】i l e 勰柚 e x 锄叩l ea n di l l 删u o 嚣t h eo p e r a t i o np c e s so fc 0 删o m l a n c et c s t b e s i 出嚣t l l a tih a v e d e v c l o p e d 锄a m o t e s tt o o l ,i tc a l lh e l p 珊i l li i l t e r o p e r a b i l i t yt 岱t ,p e r f o m a r i c et e s t 锄d r o b u s 仃l e s st e s t k e y w o r d s :b l u e c o l o t l l ;c o m ( c o m p o n e mo 巧o c tm o d i l l e ) ; a n a c c i v e1 1 即1 p l a t el i b ) ;a u t 0 储t c l a s s n o :t p 3 1 1 5 2 致谢 本论文的工作是在我的导师须德教授的悉心指导下完成的,须德教授严谨的 治学态度和科学的工作方法给了我极大的帮助和影响。在此衷心感谢三年来须老 师对我的关心和指导。 须德教授悉心指导我们完成了实验室的科研工作,在学习上和生活上都给予 了我很大的关心和帮助,在此向须老师表示衷心的谢意。 宋泽海老师对于我的科研工作和论文都提出了许多的宝贵意见,在此表示衷 心的感谢。 在实验室工作及撰写论文期间,孙东礼、李玮等同学对我论文中的蓝牙通信 原理的研究工作给予了热情帮助,在此向他们表达我的感激之情。 另外也感谢我的父母,他们的理解和支持使我能够在学校专心完成我的学业。 引言 1 1 蓝牙背景知识 l 引言 蓝牙是一种无线数据与语音通信的开放性全球规范,它以低成本的近距离无 线连接为基础,为固定与移动设备通信环境建立一个特别连接的短程无线电技术。 其实质内容是要建立通用的无线电空中接口( r a d i oa i ri n l 嚣f a c e ) 及其控制软件的 公开标准,使通信和计算机进一步结合,使不同厂家生产的便携式设备在没有电 线或电缆相互连接的情况下,能在近距离范围内具有相互操作的性能 ( i n t 蹦删i l 时) ,它可以用于各种移动设备的互联,组建个人无线局域网等,近 年已经得到了广泛的应用。 1 2 蓝牙相关术语 微微网( p i c o n e t ) 是由采用蓝牙技术的设备以特定方式组成的网络【”。微微 网的建立是由两台设备( 如便携式电脑和蜂窝电话) 的连接开始,最多由8 台设 备构成。所有的蓝牙设备都是对等的,以同样的方式工作。然而,当一个微微网 建立时,只有一台为主设备,其他均为从设备,而且在一个微微网存在期间将一 直维持这一状况。该概念主要与蓝牙角色切换操作相匹配。 分布式网络( s c a t t 锄e t ) 是由多个独立、非同步的微微网形成的【l 】。 主设备( m a s t e r 硼礼是指在微微网中,如果某台设备的时钟和跳频序列用于同 步其他设备,则称它为主设备。从设备( s l a v eu i l i t ) 是指非主设备的设备均为从 设备。 m a c 地址( m a ca d d r 鼯s ) 是用3 比特表示的地址,用于区分微微网中的设备。 休眠设备( p a r k e d u n i t s ) 在微微网中只参与同步,但没有m a c 地址的设备。监听 及保持方式( s i l i f r 锄d h o l d m o d e ) 指微微网中从设备的两种低功耗工作方式【”。 1 3 蓝牙协议体系结构 b l u e t o o t l l 技术规范的体系结构包含核心协议( c o r e ) 和应用框架( p r o f i l e ) 两 大部分【2 】,如下图所示。其中,纵轴刻画了核心协议的各个层次,横轴刻画了不同 的应用框架。 北京交通大学硕士论文 图1 1 蓝牙协议体系结构 f i g l m1 1 鼬m 咖no f b l n e 劬ms 叫【 核心协议是蓝牙技术专有的。一个特殊的层次主机控制接口层( h c i ) 把 核心协议分为硬件和软件两部分。射频( r f ) 、基带( b b ) 和链路管理( l m ) 这 三层通常固化在硬件模块上,构成核心协议的硬件部分。软件部分由逻辑链路控 制与适配协议( l 2 c a p ) 、服务发现协议( s d p ) 、串行端口仿真协议( r f c o m m ) , 电话控制协议( t c s ) 构成。它们通常运行于主机端。蓝牙系统中,主机与硬件模 块之间的连接方式可以有多种选择,如r s 2 3 2 、u s b 等。h c i 是对不同连接方式 的抽象,它提供了调用下层b b 、l m 以及状态和控制寄存器等硬件的一致的命令 接口,使得不同的连接方式对主机端的协议软件而言是透明的。 1 3 1 蓝牙核心协议 蓝牙核心协议( 见图1 2 ) 包含三个层次:网络支持层( 硬件部分) 、传输层和应 用适配层( 软件部分) 嘲。 2 引言 硬件部分 图1 2 蓝牙核心协议 f i g u r e1 2b i u e t o o 恤砷p m t d b 网络支持层:网络支持层是底部协议层包括射频、基带和链路管理三层,向 上层提供物理连接。 射频层是蓝牙技术的物理层,负责数据位流的过滤和传输。 基带( b 嬲曲a n d ) 控制部分负责跳频和蓝牙数据及信息帧的传输,包括对纠错 编码的支持,对面向连接的同步链路( s c o ) 和无连接的异步链路a c l 包的组织, 流控等同。 链路管理协议( l m p ) 实现链路的建立、认证及链路配置等f 6 】。 软件部分 传输层:l 2 c a p 构成蓝牙技术的传输层,向上层提供面向连接和无连接的数 据服纠n 。 应用适配层:s d p 、i 江c o m m 和1 s 共同构成蓝牙技术的应用适配层。 s d p 负责在蓝牙设备的邻近区域内发现服务及其属性【司。通过s d p 可以查询 远端设备所支持的服务类型和相关参数,从而可以在蓝牙设备之间建立服务连接。 r f c o m m 协议是基于e t s i0 7 1 0 规范的串行端口仿真协议。它在l 2 c a p 之 上仿真实现r s 一2 3 2 控制和数据信号,为使用串行线路传送机制的上层协议提供服 务。 t c s 协议是面向比特的协议。它以r r u - t q 9 3 l 规范为基础,定义了蓝牙设备 问建立话音和数据呼叫的控制信令。t c s 的话音连接使用s c o 链路。 北京交通人学硕士论文 在b b 和l ,m 上与l 2 c a p 之间还有一个主机控制接口层( h o s tc o n n o l l 盯 h l t e m c e ,h c i ) 。h c i 是蓝牙协议中软硬件之间的接口,它提供了一个调用下层b b 、 l m 、状态和控制寄存器等硬件的统一命令接口。h c i 协议以上的协议软件实体运 行在主机上,丽h c i 以下的功能由蓝牙模块来完成,二者之问通过一个对两端透 明的传输层进行交互。 1 3 2 蓝牙应用协议 b l u e t c 眦h 技术的应用框架大致可分为三类【4 1 :通用应用框架、基于r f c 0 m m 的应用框架和基于t c s 的应用框架。不同的应用框架之间不是独立的,它们之问 的关系如下图所示。 图1 3 蓝牙应用协议 f i g 啪蟹1 3b i u e “m t hp r o f i l e 通用应用框架:通用访问应用框架( g a p ) 和服务发现应用框架( s d a p ) 通 用于所有其它的应用框架。 g a p 定义了蓝牙设备的工作模式、安全模式以及设备发现和建立连接的通用 过程。蓝牙设备必须遵循g a p 的定义,以保证与其它设备最基本的互连性。 s d a p 定义了蓝牙网络环境下发现服务的基本流程,并提出服务发现应用的三 种可能模式。s d a p 还定义了关于服务发现的高层接口。 设备和服务的发现是访问任何服务的前提。s d a p 与下文中所述的其他应用框 架都依赖于g a p 来完成设备的发现和连接的建立,同时下文中所述的应用框架要 依赖s d a p 来完成服务的发现。 基于r f c o m m 的应用框架:其核心是串口应用框架( s p p ) 。s p p 定义了如 何在蓝牙设备上实现虚拟串行端口,仿真基于r s ,2 3 2 控制信令的串行线路。 4 引言 在s p p 的基础上,针对不同的应用模式又分别定义了局域网接入( u 诤) 、拨 号网络( d u n ) 、传真( f 强) 、耳机( h e a d s e t ) 等应用框架。它们都是基于串行端 口的。 通用对象交换应用框架( g o e p ) 是在s p p 提供的串行线路的基础上,定义了 实现对象交换的一组协议和过程,主要包括连接的建立和断开、向服务器“推” ( p u s h ) 对象和从服务器“拉”( p u l l ) 对象四种操作。文件传输( f t p ) 、对象推 送( o p p ) 和同步( s v n d l r o n i z a t i ) 应用框架都是基于g o e p 的。 基于t c s 的应用框架:目前,基于t c s 的应用框架主要包括无绳电话( c r p ) 和互连( h i c m ) 两种应用框架。c 1 1 p 使移动终端可以接入公众电话交换网 ( p s t n ) 或综合业务数字网( i s q ) ,而m e r o 蝴使移动终端之间可以通信。这 样,一部同时支持c t p 和h l 觚o m 应用框架的移动电话可兼作无绳电话和对讲机, 从而具有三合一的功能。 1 4 蓝牙数据流和控制流 在以上的协议中,数据的传输和控制信令的传递分别构成了数据流和控制流。 数据流:将高层应用的数据发送给硬件,或从硬件将数据上传给高层应用; 控制流:进行信道控制。 蓝牙可以传输同步和异步数据。同步数据一般直接由硬件接出如输出给耳机。 异步数据流则要通过软件层【i l 。 图1 4 蓝牙异步数据流 f i g u f e1 4 瑚u e t o o m4 s y m h m 肿u sd a t as t r e a m 蓝牙协议栈为高层应用提供透明信道,完成与远端高层应用的透明数据交换。 蓝牙异步数据的分层走向为: 发送数据:a p p r f c o m m l 2 c a p h c i 硬件; 接收数据:硬件- h c i l 2 c a p r f c o m m a p p 。 北京交通人学硕士论文 p 口1 i c a t i o n j tc - “,- s d p ll t c s il r f c o i l - t + c ,m , l 2 c p - j t 一一- 图1 5 蓝牙控制流 f i g u 地1 5 瑚u e 伽恤n 打o l 擘h 屯曩m 协议栈的每一层都接受上一层的命令,并向下一层发送命令,接收下一层提 交的事件,向上一层报告事件嗍。 6 组件的原理 2 1 组件的概念 2 组件的原理 一个应用程序通常是出单个的二进制文件组成。当编译器生成此应用程序以 后,在对下一版本重新编译并发行新生成的版本之前,应用程序一般不会发生任 何变化。为了解决这个矛盾,开发人员将单个应用程序分隔成多个独立的部分, 也即组件。 组件应用程序 圆圈 圆圈 二至巫 图2 1 将单个应用程序( 左) 分割成多个组件( 右) 。可使之适应各种变化 f i g u l e2 1d i v i d eu po n e8 p p l i c a t i o ni n t os e v e r a lc o m p o n e n t s 这种做法的好处是可以随着技术的不断发展,用新的组件取代已有的组件。 ( 参见图2 2 ) 此时的应用程序将不再像以前那样在发行之自口就已命中注定要过时 的静态实体,而是可以随着新组件不断取代旧的组件而趋于完善。并且从已有的 组件可以建立全新的应用。 组件应用程序 i 组件a组件b l - - ,- - - - - - - - - - 、- - - - - - - - - - - - - - - - 一l - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 一 l 组件c新的改进后的组件d l 组件e 图2 2 用改进后的新组件d 取代原有的组件d f i g u r e2 2r e p l a c ec o 册p o n e n td ,i t h 锄i p r o v e do n e 如何将应用程序拆分成一个个的组彳孛呢? 这就需要采用c o m 技术了“。 c o m ,即组件对象模型,是关于如何建立组件以及如何通过组件构建程序的应用 规范。其目的楚使各种软件产品更加灵活、更具有动态性并且易于定制。它提供 了为保证能够互操作,客户和组件应遵循的一些标准。标准对于组件架构的重要 性同其他任何一个具有可改变部分的系统是一样的。 c o m 组件是以w i n 3 2 动态链接库( d l l s ) 或可执行文件( e x e s ) 的形式发 7 北京交通人学硕士论文 布的可执行代码组成的。遵循c 例规范编写的缎件将能够满足对组件架构的所有 需求。但是,动态链接本身并不能满足对于组件架构的需求,在此基础上必须满 足封装性。 对c o m 组件豹封装是很容易的,只要满足以下一些限制条件即可: c o m 组件是完全与语言无关的。 c o m 组件可以以二进制的形式发布。 c o m 组件可以在不妨碍老客户的情况下被升级。 c o m 组件可以透明的在网络上被重新分配位置。 c o m 组 牛可以为其它应用程序提供面向对象的a p i 或服务,可以快速构建应 用程序、建立与语言无关的组件库。 2 2 组件的表示 在w i n d o w s 中所有的应用程序都是以组件的方式实现的,而且随着应用程序 的增加,组件的数目也会大幅度上升。在程序运行的时候,后台其实是透过一个 标识找到某个组件然后调用该缎件的接口函数( 接口的概念后面介绍) 。所以每个 组件都必须有唯一的标识,这样调用起来才不会发生问题,这个标汲就是 c l s i d 洲。 c l s i d 是一个1 6 字节的数字,在系统注册表的h k c r 、c l s i d f ,主键下。 在l o c a l s e r v e r 3 2 ( d u ,组件使用h l p r o c s e r v e r 3 2 ) 中保存着应用程序的路径名称, 当系统调用一个组件的时候就是通过这个路径找到对应的组件应用程序。 c l s i d 的结构定义如下: t y p c d e f s 咖c t p u i d d w o r dd a t a l :,随机数 w o r dd a t a 2 :和时间相关 w o r dd a t a 3 :,和时间相关 b y r ed a t “【8 】;,和网卡m a c 相关 ) g 村i d ; t y p e d e f g u i dc l s i d ; 组件d 啪e d e f g u i di l d ; 接口i d ( 下一节介绍) 蒯e f i n er e f c l s i dc o n s tc l s i d & 例如常见的声明和赋值方法 c l s i d c l s i d x c e l = o 】【0 0 0 2 4 5 0 0 ,o x o o o o ,0 】【0 0 0 0 , 0 x c o ,0 ) 【0 0 ,o x 0 0 ,o x o o , o ) 【o o ,0 】【o o ,o x o o ,o “6 ) ) ; 组件的原理 s 饥l d g o d s p c c ( i d ( ”o 0 0 2 4 5 0 0 - 0 0 0 0 0 0 0 0 - c 0 0 0 0 0 0 0 0 0 0 0 0 0 4 6 ) ) c l s i d _ e x o d ; c l 勰sd e c l s p e c - w m ( ”0 0 0 2 4 5 0 0 一0 0 0 m o o o o c 0 0 0 - o 蝴o 0 0 4 6 ”) c l s i d i - l 三x l ; ,注册表中的表示方法 0 0 0 2 4 5 0 0 - 0 0 0 0 o o o o - c o o o - 0 0 0 0 0 0 0 0 0 0 4 6 通过c l s i d 就可以保证组件的唯一性。 每一个c 0 m 组件都有一个c l s i d ,并且保证不会重名。同时微软为了使用 方便,也支持另一个字符串名称方式,叫p r o g m ,在注册表的p f o g i d 子键中 由于c l s i d 和p r o m d 其实是一个概念的两个不同的表示形式,所以在程序中可 以随便使用任何一种( p m g i d 由于使用字符串很可能会重名) 。系统的a p i 提供了 函数可以生成、比较c l s i d ,同时支持c l s i d 和p r o g i d 之间的转化。 2 3 接口 在c 0 m 中接口是最重要豹概念,一个组件就是一个接口集,客户通过接曰与 组件交互“。对于应用程序来说接口才是最重要的,组件只不过是接口的实现细 节。 接口 罔 二二 二 i 宁l 二3 二二 覆i 订圃与割 耍垂垂回e 匿豆圃 爿 璧旦回 二】 i 富l 二】 二 耍王垂固l 刳 蔓垂亘圈 幽2 3 在c o 垂中接口比实现接口的组件更重要 f i g u r e2 3i i i t e r | h 钟i sm o 弛i n i p o r t a n tt h 粕c o m p o n 蚰tj t 卵盯 只要接口不变,组件可以随意更换,这样就可以设计出可复用的程序结构。 组件是具有封装性的,以“把一个对象的外观( 接口) 同其实际工作方式( 实 现) 分离开来”为基础。调用程序在并不完全清楚组件实现什么功能的情况下仍 能谜用接口中的函数。 2 3 1 如何得到接口指针 为能使c o m 具有跨语言的能力,它不再为任何语言提供对应的函数接口声 9 北京交通人学硕士论文 明,而是独立地提供一个类型库( t l b ) 的声明。每个语言的i d e 环境根据t l b 生成自己需要的包装,这个性质叫“接口声明的独立性”。由于c o m 是与语言无 关的,对于接口它有一个二进制标准就是说表示一个接口的内存块必须具有一定 的结构,该结构与c 十上中抽象基类所生成的内存结构是相同的。因此接口的定义采 用该方式,可以通过虚函数表得到接口函数地址。 但足仅仅依靠虚函数表足不够的,在c 例组件中所有的接口都还必须继承一 个i u n k n o w n 接口。i u n k n o w l l 接口定义如下: i m e r 缸ei u r i h l o w n v i m l a lh r e s u 【d t d 硎lq u e r i n t e 嘞c c o n s tl i d i i d ,v o i d 幸p p v ) = o ; v i n 吼lu l c n g s t d c a l la d d r e 坟) _ o ; v i r t i l a lu l o n g s t d c a l lr d e a s ) = = o ; 通过q 毗呵i n t e 以c e 来决定组件是否支持某个特定的接口,a d d r e f 和r d e a s e 用予控制接口的生命周期。只要知道了一个i u n l 【n o w n 接口的指针,就可以用它来 查询其它接口。由于所有的c 删接口都派生自i u n k n o w n 接臼,它们的前三个函数 都是q u 砌e 施c e 、a d d r e f 和r d e a s e 。所有的接口都支持q u e f y i t l t e 面c e ,因此 组件中的任何一个接口都可以被用户用来获取它所支持的其它接曰。这样就不需 要单独维护一个代表组件的指针,可以把全都注意力集中到接口指针上来。 假设一个组件支持两个接口i f 、i k 。瑾接口中有f l ( ) 、f 2 0 、f 3 ( ) 三个瞬数, l k 接口中有k 1 ( ) 、k 2 ( ) 两个函数,根据图2 4 就呵以得到函数的实现体。 图2 4c 叫接口结构 f i g u l e2 4s b n i c t 件o f c o mi n t e r f h 为了描述方便,一般使用下商的简洁样式: l o i u d o w n 旨钟 i f 指钟 组件的原理 庠 图2 5o 嘲接口结构的简洁图示 f i g t l r e2 5s i i n p i e c o m i n t w f a c e 可以通过一个c r c a t e i l l s t a 以c c 来建立一个组件并返回一个i u l l k n o w n 指针: i u n k n o w n 幸c e a t e i l l s t a n c e ( ) : 在此只是介绍此函数的一个简单版本,在以后章节中还会详细介绍。至于到 底得到哪个组件的i u n k n o w n 指针,就要根据所引用豹类型库来决定了。当得到一 个i u n k l l o w n 指针以后就可以通过q u e f y i n t e 嘞c e 来得到其它接口了。 2 3 2 q i l e r y i n t e r f a c e 函数 q i l e r y i n t e m c e 成员函数包含在i u n l 【1 1 0 w l l 接口中,客户透过它查询组件是否 支持某个特定的接口,若支持,将返回一个指向此接口的指针,否则返回值是一 个错误码。 q u c r y i n t e 尥c e 带有两个参数: h r e s u l t s t d c a l lq u e r y i n t e m c e ( c o n s ti i d & i i d ,v o i 扩p p v ) ; 第一个参数足接口标识符常量,在2 2 节中可知它是一个1 6 字节g u i d 结构, 通过它来保证接口标识符的唯一性,当调用q 懈叫i n t e r f a c e 函数的时候不会得到其 它豹接口指针。另外一个指针是存放所请求接日指针的地址。它将返回s k 或 en o i n t e r f a c e ,返问值的意义和使用方法将会在后睡章节介绍。 当得到了一令指向i u n k n o w n 的指针p l ,就可以直接使用它的q u e r y i n t e r f a c c 函数查询接口指针了。但是注意q u e f y b t e 廊c 的功能要满足以下几点: q u e r y i n t e l f a c e 返回的总是阉一个i u n k l l o w n 指针。 若客户曾经获取过术各接口,那么它将总恩能够获取此接口。 客户可以再次获取已经拥有的接口。 客户可以返回到起始接口。 若能够从未各接u 或出某特定接口,那么可以从任意接口都将可以获取此 接口。 只有满足以上几条规则,l + 能通过该函数查询组件的接口指针。 下面将通过代码说明q u e r y i m e 出c e 函数的实现。一个组件支持、l y 两个 北京交通人学硕+ 论文 接口,此处它可以返回三种不同的接口指针:l u n l ( i l o w n 、i x 及i y 。在上一节中介 绍用纯抽缘类可以表示一个接口,在此用类c a 表示接口,它继承了砌n h o w n 接 口i x 和i y 。在此返回的l u n k n o w n 指针都足一个,即c a 的指针。 h r e s u 【码t d c a l lc a :q u e r y i n t e r f a c c o n s ti l d & i i d ,v o 主d + 。p p v ) i f ( i i d i i d i u n l m o w n ) 毒p p v = s t a t ic - c 鹊t ( t l l i s ) ; ) e l s ei 琊i d i i d - - i x ) 卓p p v = s t a t i cc 勰t ( t 量讧s ) ; e l s e i i i d 一皿一) 搴p p v = s t a t i 删t ( t h i s ) ; e l s e ( + p p v 2 n u l l ; r e t t l me - n o i n t e r f a c e ; ) s t a t i c i c a s r ( i u n k n o w n 牵 ( + p p v ) - a d d r e 坟) ; r e t u m s o i ( ; 微软的a t l 中的智能c o m 已经为我 f j 封装好了q u e r y l m e r f 犯e 函数,在实现 c o m 组件的时候直接调用宏就可以了1 ,在此只是简要介绍该函数的原理。 2 3 - 3 接口的生命周期 在i u n l 【i l o w n 接口中,除了q u e r y i n t e r f a c e 还存另外两个函数a d d r e f 和 r e l e a s e ,即弓l 用计数,它们用来控制援u 的生命周期。 假设在应用程序中有一个组件c a ,并且有若干个指向此c a 接口的指针。当使 用完一个接口两仍要使用另外一个接口的时候足不能将组件释放聿卓的。但跫由予 1 2 组件的原理 很难知道任意两个接口的指针是否指向弼一个组件,必须要查询两个接口的 i u f l k n o w n 指针,然后对结采进行比较,因此决定何时可以安全的释放一个组件是 比较复杂的。但是又不能在整个程序的运于亍期内一直装载该组件。因此,我们采 用引用计数的方法,在客户使用完组件的各个接日以后出它自己去释放,a d d r e f 和r d e 勰e 就是做该工作的。c o m 组件维护一个引用计数的数值,当客户从组件 取得一个接口的时候,此引用计数值增l ,当客户使用完某个接口后,组件的引用 计数值将减1 ,当引用计数为0 时,组件即可将自己从内存中删除。当创建某个已 有接口的另外一个引用的时候,客户也会增大相应组件的引用计数。a d d r e f 增大 引用计数值,r d e a s e 减小该值。 正确的使用引用计数要遵循下面三个规则: l ,在返翻之前调用a d d r e f o 对于那些返回接口指针的函数,在返回之前应 用相应的指针调用a d d r e f a 这些函数包括q u e r y i n t e r f a c e 及c r e a t e i n s t a n c e 。 这样当客户从这种函数得到一个接口后,它将无需调用a d d r e 厶 2 使用完接口后调用r e l e a s e 。在使用完某个接口之后应该调用此接口的 r e l e a s e 函数。 3 在赋值之后调用a d d r e 厶在将一个接口指针赋给另外一个接口指针时, 应调用a d d r 乩换句话说,在建立接口的另外一个引用之后应增加相应 组件的引用计数。 引用计数的实现比较简单,在此不作介绍。同q u e r y l n 衄f a c c 一样a t l 的能 c o m 也替我们把该工作完成了。 2 4 组件的数据类型 首先需要说明一下,c o m 组件是运行在分布式环境中的。一个组件程序( d l l 或e x e ) 的调用者可能是在本机的某个进程内加载组件( i n p r o cs e r v e r ) ,也 可能是从另一个进程中调用组件的进程( l o c a ls e r 、,e r ) ,还可能是在这台计 算机上调用地球那边计算机上的组件( r e m 0 1 晤s e r 、,e r ) 。可见在运行期间可能 发生许多异常情况,因此组件的接口函数除了要返回运算结果之外还应该返回一 个值( h r e s u l t ) 表示函数是否被正常执行了 如果函数正常执行,则返回so k ,同时真正的函数运行结果刚通过参数指 针返回。如果遇到了异常情况,则c o m 系统经过判断,会返回相应的错误值。常 见的返回值有: 1 3 北京交通大学硕十论文 表2 1 :c o m 接口函数可能的返回值 t a b l e2 1v a l u e sc o mi n t e r f h m a yn t l i m h r e s u i j值 含义 so ko x 0 0 0 i ) 0 0 0 0 成功 sf a l s e o x 0 0 0 0 0 0 0 i函数成功执行完成,但返回时出现错误 en a l i d a r g o x 8 0 0 7 0 0 5 7参数有错误 e - _ o u r c 悯m o r y o x 8 0 0 7 0 0 0 e内存申请错误 e u n e e c r e d o x 8 0 0 0 f f f f 未知的异常 en o t i m p lo x 8 0 0 0 4 0 0 1 未实现功能 ef a 【lo x 8 0 ( ) 0 4 0 0 5 没有详细说明的错误。 e - - p o 咖r o x 8 0 4 0 0 3 无效的指针 eh a n d l e0 x 8 0 0 7 0 0 0 6 无效的旬柄 ea b o r t o x 8 0 0 0 4 0 0 4终止操作 e a c c e s s d e n i e d o x 8 0 0 7 0 0 0 5 访问被拒绝 e _ n o d 盯e i 吼c e o x 8 0 0 0 4 0 0 2 不支持接口 幽2 6h r e s u 【t 的结构 f i g i l f e 2 6 蜘l c | n o fh r e s 阱j h r e s u l t 其实是一个双字节的值,其最高位( b i t ) 如果是0 表示成功,1 表示 错误。如果要判断返回值不能直接与上面的值进行比较而应该用宏。 h r e s u u l l r = 调用组件函数; i f 【s u c c e e d e d ( 1 u ) ) ,如果成功 i f 【f a i l e d ) ) 如果失败 c o m 中除了使用一些简单标准的数据类型外,字符串类型是特别需要注意 的。由于c o m 组件是运行在分布式环境中的,不能直接把一个内存指针赢接作 为参数传递给c o m 函数,系统起码簧知道这个内存块的尺寸,有多少个字节才能 够传递。 因此c 0 m 引入了b a s i c 中字符串类型的表示方式一b s t r 。b s t r 其实足一个指针 类型,它的内存结构如图( b s t rp = :s y s a l l o c s t r i n g ( l ”h e l l o ,你好”) :) : 1 4 组件的原理 il o l0 0 10 0 l0 0 4 8i 6 5l0 06 c0 06 c l0 06 f0 02 cl 6 0 l4 f7 d l5 9 0 00 0 i长度1 6 字节 hjl0 你好 b s t r 幽2 7b s 俅内存结构 f i g u i e 2 7s t 加c t h 件o f b s t r j nm e 啪r y b s l r 是一个指向u n i c 0 d e 字符串的指针,且b s t r 向前的4 个字节中,使 用d w o r d 保存着这个字符串的字节长度( 没有含字符串的结束符) 。因此系统 就能够正确处理并传送这个字符串到任何地方了。由于b s t r 指针就是指向 u n i c o d e 串,因此可以说在c 0 m 组件中所有的参数传递都必须是l 玳i c o d e 的。 使用a t l 的宏可以进行各种字符集之闻的转换。 另外一种数据类型就v a l u a n t 它具有跨语言的特性,同时它可以表示( 存 储) 任意类型的数据。从c 语言的角度来讲,匮队n t 其实是一个结构,一结构 中用一个域( 呐表示该变量到底表示的是什么类型数据,同时真正的数据则存 贮在u l l i o n 空间中。咀队n t 的结构 i i j 如下: t y p e d e f s 咖c tt a g v a r 队n t v a r t y p e 丑; u n s i 驴e ds h o r tw r 岱e f v e d l ; m s i 鲷c ds h o r tw 胁e r v c d 2 ; u i l s i 印e ds h o r tw r 嚣e r v c d 3 ; 砌o n m s i 印c dc h a rb v a l ; s i l o r t i v a l : l o n gl v a l ; n o a tn t v a l : d o u b l ed b l v a l : v a r i a n tb o o l b o o l v a l ; s c o d es c o d e : c y c y v 扯 d a t e d a t b s t rb s w a l : n j n l m o w nf a r + p l m k ; 北京交通大学硕+ 论文 i d i s p a t c hf a r + p d i s p v a l ; s a f e a r ra yf a r 幸p 棚删 啪s i 舻e dc h a rf a r + p b v a l ; s h o r tf a r + p i v a l ; l o n g f a r + p l v a l ; n o a tf a r 奉p n t v a l ; d o u b l ef a r + p d b l v a l ; v a r i a n t _ b o o lf a r 幸p b o o l v a l ; s c o d e f a r p s c o d e ; c yf a r p c y v a l ; d a t e f a r 幸p d a t e ; b s t rf a r + p b s 0 v 硐; i u n h o w nf a r 事f a r p p u n k v a l ; i d i s p 砷c hf a r + f a r p p d i s p v a l ; s a f e a r ra yf a r 幸f a r p p 黝y ; v a r i a n t f a r 幸p v a r v a l ; v o i d f a r + b 弘吐 ) ; ) ; t y p e d e f s 虮l c tf a r s t r u c tt a g v a r i n tv a r i a n t ; t y p c d e f s 仉l c tf a r s t r u c tt a g v a r i a n tv a r i a m 队r g ; 具体每个参数的含义可以参考赫s 删。 2 5 建立组件 在前丽接口一节中通过调用c r c a t e i n s t a i l c e 函数来建立组件,在这节我们将 详细介绍组件的建立过程。 在系统中有一个c 0 m 摩,我们在对其进行初始化以后可以直接调用其中的库 豳数建立组件。在c o m 摩中包含一个用于刨建组件的函数c o c r c a t e l n s t a n c e ,它 需要一个c l s l d 参数来刨建维件。 c o c r c a t d n s t a l l c c 的声明如下: h r e s u l t t d c a l lc o c r e a t e i n s t a n c e ( c o n s tc l s i d & c l s i d i u n k n o w 矿p i u n k n o w n 0 i i l t 1 6 组f i :的原理 d w o r dd w c l s c o n t e n l c o n s ti i d & i i d v o i d + + p p v ) : c o c r 髓t e i n s t a n c e 有四个输入参数和一个输出参数。第一个参数是待创建组件 的c l s i d 。第二个参数是用于聚合组件的,将在后面讨论。第三个参数作用足限 定所创建组件的执行上下文。第四个参数为组件上待使用的接口的i i d 。最后一个 参数返回此接口的指针。通过将接口i i d 蠢接传给c o c r e a t e i n s t a i l c e ,这样客户将 无需再创建组件之后去调用其q 嘴哼i n t e 瓜c e 函数。 c o c r e a t e i n s t a n c e 的使用同q u e r y i n t e r f a c e 是一样简单的: p = n u l l ; h r e s u l t 1 l r = :c o c 廊t e h

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论