一种命名服务机制的制作方法

文档序号:6561258阅读:217来源:国知局
专利名称:一种命名服务机制的制作方法
技术领域
本发明涉及一种命名服务机制,尤其是一种通过字符串与命名服务对象的对应关系来找到组件对象的命名服务机制。
背景技术
零部件动态装配(Component Assembly Runtime,简称CAR),是一种构件技术。CAR构件技术是面向构件编程的编程模型,它规定了一组构件间相互调用的标准,使得二进制构件能够自描述,能够在运行时动态链接。
CAR与微软的组合对象模型(Component Object Model,简称COM)类似,但是和微软COM相比,CAR删除了COM中过时的约定,禁止用户定义COM的非自描述接口;完备了构件及其接口的自描述功能,实现了对COM的扩展;对COM的用户界面进行了简化包装,易学易用。
从上面的定义中,我们可以说CAR是微软COM的一个子集,同时又对微软的COM进行了扩展,在软件开发工具包(Software Development Kits,简称SDK)的支持下,使得高深难懂的构件编程技术很容易被C/C++程序员理解并掌握。
命名服务是CAR体系里面的一项重要技术,CAR体系的组件实现了较为完善的自描叙功能,其有一套成熟的可以穿透不同机器,进程以及其它不同访问限制空间的组件交互技术。命名服务在该体系中担当了一种发布,发现并获得组件服务的策略机制。
现有的命名机制类同于微软COM的名字对象机制COM的名字对象机制,是一种标准的,可以把任意的对象名字解析到这些名字所引用的对象上的方式。其支持三种激活方式绑定到类对象,绑定到新的类实例,以及绑定到保存在文件中的永久对象。下面介绍相应的各个过程的C++代码实现1、绑定到类对象//本例通过获得一个大猩猩的类对象,然后通过其创建一个类实例IclassFactory*pcf=0;//声明Gorilla的CLSID为显示名const OLECHAR pwsz[]= OLESTR(″clsid571F1680-CC93-1100-2000-001223113344″);//通过Gorilla的类名字对象寻找类对象HRESULT hr=CoGetObject(pwsz,0,IID_IclassFactory, (void**)&pcf);if(SUCCEEDED(hr)){IApe*pApe=0;//使用类对象创建Gorillahr=pcf-> CreateInstance(0,IID_IApe,(void**)&pApe);......
}2、绑定到类实例//本例通过获得一个命名的类实例IApe*rpApe;HRESULT hr;//类对象名(clsid)和类实例名(Ursus)的组合const OLECHAR pwsz[]= OLESTR( ″clsid:571F1680-CC93-1100-2000-001223113344:!Ursus″);hr=CoGetObject(pwsz,0,IID_IApe,(void**)&rpApe);3、绑定到保存在文件中的永久对象//本例获得一个保存在文件中的类实例IApe*rpApe;HRESULT hr;//文件的路径和文件名OLECHAR pwszObject[]= OLESTR(″ server public cornelius.chmp″);hr=CoGetObject(pwszObject,0, IID_IApe,(void**)&rpApe);
因此,从上可以看出,微软的名字对象对外提供了统一的接口函数获得对象函数(CoGetObject)。但从CoGetObject的实现来看,它将创建对象本身与绑定名字两个过程合在一起,也就是说当不存在字符串所指定的对象或者实例的时候,它将创建一个对应的新的对象或者实例来满足用户的要求。用户也无法自己指定特定的类实例进行绑定。而对于绑定类对象来说,COM规定组件的类对象必须实现解析显示命名(IparseDisplayName)接口才能使用名字对象绑定类对象的功能;对于绑定到保存在文件中的永久对象,则组件本身必须实现永久文件(IPersistFile)接口,名字对象机制的使用对组件本身的实现有限制和需求。它也不支持将一个远程接口代理和字符串绑定的功能。

发明内容
本发明的目的是提供一种命名服务机制,支持远程接口代理,可以实现字符串与对象的绑定,而且允许将任意接口代理与字符串绑定,从而达到组件服务与提供命名服务可以不为同一用户的能力,更有利于组件服务的分发和使用。
为实现上述目的,本发明提供了一种命名服务机制,包括以下步骤步骤1、服务端进程获得一个组件对象的指针;步骤2、服务端进程将获得的组件对象的指针与一个字符串绑定,并注册到内核,获得组件对象在内核的注册信息对象,内核创建一个代表命名服务的命名服务对象,并将命名服务对象以所述字符串为标志与注册信息对象绑定;步骤3、客户端进程利用所述字符串查询获得所述命名服务对象;步骤4、客户端进程找到绑定的所述字符串对应的注册信息对象;步骤5、客户端进程通过所述注册信息对象和字符串找到组件对象的指针。
在所述步骤5之后还包括步骤6、客户端进程利用所获得的组件对象的接口指针调用组件方法;步骤7、客户端进程释放所述组件对象接口指针,通知服务端进程。
所述步骤7之后还具有以下步骤步骤8、服务端进程注销所述命名服务对象;步骤9、服务端进程释放所述组件对象的接口指针。
因此,本发明命名服务机制,可以支持远程接口代理,可以实现字符串与对象的绑定,而且允许将任意接口代理与字符串绑定,从而达到了组件服务与提供命名服务可以不为同一用户的能力,更有利于组件服务的分发和使用。即通过用字符串的方式向外发布组件,而异空间的其它用户则可以通过命名服务获取组件服务。用户和内核都可以创建一个命名服务,其它用户可以透明的获得该用户指针,而无需考虑其所在位置空间的不同。命名服务server端获得的组件指针代表的可以是其server进程内空间创建并运行的组件,亦可以是一种基于CAR构件技术的嵌入式操作系统内核提供的以接口形式提供的内核功能,也可以是server端所获得的其它进程所实现的组件服务。相关组件服务动态更新或者升级,不影响其它通过命名服务获取该服务的程序,其依然可以无需改动,无需重新编译地正常工作。
下面结合附图和实施例,对本发明的技术方案做进一步的详细描述。


图1为本发明命名服务机制的方法流程图。
图2为本发明命名服务机制EzFindService API函数的实现流程图。
具体实施例方式
本发明的思想是设计一种以字符串为标识的服务。服务程序可以通过操作系统API函数注册服务函数(EzRegisterService)向操作系统注册自己的服务接口,而服务的使用者(即客户端程序)则可以通过API函数获取服务函数(EzFindService)来获取指定的服务接口。命名服务通过简单,友好的系统API函数,为系统服务以及用户组件提供了一套完整的CAR构件使用流程,具有良好的扩展性,并支持基于组件的动态更新和升级。
命名服务机制属于CAR构件技术的一部分,CAR构件技术通过命名服务机制提供一种发布,获取,使用CAR构件的方法,命名服务隶属于CAR构件技术的用户接口部分。
首先,我们实现一个简单的动态链接文件(Dynamic Link Library,简称dll)形式的CAR组件服务,主要C++代码如下在hello.car文件中组件,实现类、接口,以及方法的声明表示如下[version(1.0),uuid(e363b985-8a3a-40a6-b88c-b2e10274fe54),uunm(www.koretide.com/ezcom/hello.dll)]component Hello//组件Hello{[uuid(70f1f7e4-1b9b-4e74-8c1b-fdc2fefblce1)]interface IHello{//接口IHelloHRESULT Hello([in]EzStr inStr);//方法Hello}[uuid(3d19bc4c-b2c7-4ea5-8409-63db930adlb7)]class CHello{//实现类CHellointerface IHello;}}在chello.h以及chello.cpp文件中声明了C++类型的CHello对象,并实现接口方法Hello。
chello.h文件中主要C++代码表示如下class CHello:public_CHello//CHello定义{public:
STDMETHODIMP Hello(/*[in]*/EzStr inStr);};chello.cpp文件中主要C++代码表示如下
DECLARE_ LASSFACTORY(CHello)//声明类厂HREsULT CHello::Hello(//Hello方法的实现代码/*[in]*/EzStr inStr){printf(″%S n″,(wchar_t★)inStr) ;return S_OK;}在server.cpp中,我们将创建一个Hello的本地组件,并将其注册为以字符串“ hello”为标志的命名服务对象,然后我们通过系统API函数创建事件(EzCreateEvent)获取一个内核Event对象服务,并将其注册为“event”为标志的命名服务,服务使用完毕,注销服务,并释放相关资源。程序主要C++代码如下CHelloRef cHello;//声明接口智能指针IEvent★pEvent;//声明Event接口指针//在本进程空间内创建一个Hello组件HRESULT hr=cHello.Instantiate();if(FAILED(hr)){……}//注册命名服务,将CHello构件与字符串“hello”绑定hr=EzRegisterService(EZCSTR(″hello″), (IHello★)(cHello);if(FAILED(hr)){……}//通过API函数获得一个内核Event对象服务hr=EzCreateEvent(true,false,&pEvent);if(FAILED(hr)){……}//注册命名服务,将Event构件与字符串“event”绑定hr=EzRegisterService(EZCSTR(″event″),pEvent);if(FAILED(hr)){……}//让该进程等待pEvent->Wait(NULL);
//被其它进程唤醒,等待结束,注销服务,释放资源EzUnregisterService(EZCSTR(″event″));//注销Event服务pEvent->Release();//释放pEevent指针//cHello为对象智能指针,所以程序退出,它会自动释放对象资源EzUnregisterService(EZCSTR(″hello″));//注销hello服务在client.cpp中,我们将通过EzFindService函数使用以字符串“hello”以及“event”为标志的命名服务对象,通过命名服务对象,我们找到与命名服务对象的名字绑定的相关组件服务,并进行调用,调用完释放掉相关的组件服务指针。主要C++代码如下IHello*pIHello;//声明一个IHello接口指针IEvent*pIEvent;//声明一个IEvent接口指针HRESULT hr;//通过字符串“hello”找到相关组件服务hr=EzFindService(EZCSTR(″hello″),&pIHello);if(FAILED(hr)){……}//远程调用Hello方法,打印″hello,world″pIHello->Hello(EZCSTR(″hello,world″));pIHello->Release();//释放获取的IHello接口指针//通过字符串“event”找到相关组件服务hr=EzFindService(EZCSTR(″event″),&pIEvent);if(FAILED(hr)){……}//通过notify方法唤醒server进程pIEvent->Notify(0);pIEvent->Release();//释放获取的IEvent接口指针上述实施例流程图如图1所示,步骤1、服务端进程获得一个组件Hello的指针;本进程空间内创建一个Hello组件;通过EzCreateEvent API函数获得一个内核Event对象服务,步骤2、服务端进程将创建的组件对象Hello与一个字符串“Hello”绑定,并注册到内核,获得组件对象在内核的注册信息对象,内核创建一个代表命名服务的命名服务对象NameHook,并将命名服务对象NameHook以字符串“Hello”为标志与注册信息对象绑定;并注册为“event”为标志的命名服务;即Server程序装载组件,注册成功以“hello”,“event”为标志的命名服务;步骤3、客户端进程利用字符串“hello”查询找到相关的组件命名服务对象NameHook;步骤4、客户端进程找到绑定的注册信息对象Object;步骤5、客户端进程通过注册信息对象和字符串“hello”找到组件对象Hello的指针。
用户一旦通过命名服务获得某个组件服务,其与组件服务交互的过程不再需要与命名服务相关联。即步骤5完成以后,客户端进程得到了服务进程中命名服务所对应的组件指针包括本地组件指针或者远程组件指针,他们之间的通讯通过组件调用或者远程接口通讯方式进行,而与命名服务组件无关。
上述步骤1至步骤5完成了用户和内核都可以创建一个命名服务,其它用户可以透明的获得该用户指针,而无需考虑其所在位置空间的不同。用户一旦通过命名服务获得某个组件服务,其与组件服务交互的过程不再需要与命名服务相关联。因为组件对象与命名服务对象相对独立,命名服务只是将字符串和组件服务对象关联,因此相关组件服务动态更新或者升级,不影响其它通过命名服务获取该命名服务的程序,其依然可以无需改动,无需重新编译地正常工作。
在上述具体实施方式
,更好的实施是在上述步骤5之后,还包括如下的流程步骤6、客户端进程调用组件Hello的服务函数;步骤7、客户端进程通过Event对象通知服务端进程,释放组件Hello的接口指针,client进程退出;在步骤7之后,服务端进程也可以进行注销步骤8、server进程接到通知后注销命名服务;步骤9、server进程释放组件Hello的指针,并退出。
在步骤9之后,如果客户利用所述字符串从内核获得所述组件接口指针,将无法获得,并且返回错误。
上叙事件的等待,以及进程间事件的通知过程的实现是通过内核对象event实现的,进程间event指针的获取亦是通过命名服务获得的。
命名服务机制的实质是将一个组件和指定的字符串绑定的过程,组件使用者可以远程通过字符串查询该组件,并获得组件服务。命名服务本身即可以作为一个单独的构件存在,亦可以作为内核功能的一部分。
远程CAR组件在创建的时候会向内核注册相关信息,并建立存根,称为Stub,远程用户获得组件指针的时候在自己进程空间建立代理,称为proxy。
远程CAR组件在内核注册的信息代表了该组件对象的存在,我们通过一个内核对象Object代表某个组件的注册信息,通过此信息,可以找到相关建立代理所必须的信息,另一方面,也可通过这些信息找到该远程组件以及组件服务相关信息。
命名服务的实现主要是通过在内核创建代表一个命名服务的对象NameHook,然后将该对象与该命名服务绑定的组件对象在内核的注册信息对象Object相绑定,NameHook,Object,Stub对象在系统里面存在一一对应的关系,这样通过字符串就可以找到相应的NameHook,通过NameHook则可以发现相应组件对象的Object,通过Object又可获得足够建立Proxy的信息。
而对于注册一个命名服务,则是通过API函数EzRegisterService完成的,该API函数将一个字符串与一个组件接口相绑定,实际上这里的组件接口也可能是一个远程组件接口代理,这样就分成两种情况做不同的处理1、接口是一个远程组件接口代理,则通过接口代理,找到相应的Object,然后创建命名对象NameHook,将二者绑定。
即,步骤1中组件的指针为远程组件指针,是指组件的远程接口代理,该指针实际上是一个代理proxy对象指针,远程组件指针与内核中一个存根stub对象以及注册信息对象唯一对应;可以存在多个proxy对象和一个stub以及Object对象对应的情况,步骤2获得组件对象在内核的注册信息对象具体为根据远程组件指针与内核中一个存根stub对象以及注册信息对象唯一对应得关系找到注册信息对象。
其中,接口是一个远程组件接口代理,上述步骤1-5过程如图2所示EzFindService API函数的实现流程,通过查询字符串获得命名对象NameHook,由命名对象NameHook的标志字符串如“hello”找到注册信息对象Object,找到注册信息对象后,根据远程组件指针与存根stub对象以及内核中一个注册信息对象唯一对应得关系找到组件对象。
2、接口是一个本地对象接口指针,则创建或者找到相应的存根(stub),然后向内核注册相关信息,并生成Object对象,创建命名对象NameHook,将二者绑定。
即,步骤1中组件的指针为本地组件指针;步骤2获得组件对象在内核的注册信息对象具体为服务端进程通过本地组件指针,找到或者创建存根stub对象,生成和存根stub对象相关联的注册信息对象。
相对于命名服务对象所获得的组件对象,命名服务对象亦是一个普通的组件使用者,提供命名服务的程序可以选择在一个合适的时间点释放该组件服务指针。所有适应于CAR构件生命周期管理的操作和语义亦适应于命名服务,命名服务也是一种组件服务。并且,命名服务的生命周期由命名服务创建者所控制,但使用命名服务的程序可以通过系统事件,或者进程间通讯给服务创建者相关服务使用信息,命名服务创建者可以通过对服务使用情况的分析来选择退出时机,符合普通car组件的生存原则。
调用注销服务函数(EzUnregisterService)注销命名服务,其实是取消NameHook对象与相应Object对象的关联,以及销毁NameHook的过程。在取消关联的同时,会释放相关组件指针,并不再允许用户通过命名服务获得组件服务。
鉴于命名服务和关联组件可能属于不同用户所构建,则关联组件有可能提早被其所属进程退出,或者发生异常,提前退出,内核则会检测到这种情况的发生,销毁NameHook以及Object对象以防止该组件指针再被用户利用。而以往获得的组件指针将会全部失效,在调用过程中内核会返回一个错误值,以通知用户。即,相关组件服务退出,命名服务不再有效,其它再试图通过命名服务获取相关组件服务的程序将返回错误。所有命名服务以及相关组件服务资源都已回收,上述步骤3将返回错误。
因此,本发明命名服务机制具有以下特点1、用户程序通过字符串获取相关服务,而服务则可由系统,以及其它用户程序提供,这样将服务和服务使用者隔离的方式,减小了代码的耦合性,极大的增强了代码的可扩展性,安全性,同时也最大的发挥了系统的功能。
2、从扩展性来看,用户可以通过在保持接口定义不变的情况下,修改服务程序代码,升级服务程序;另一方面用户亦可以通过提供新的接口,来扩展新的功能,新的用户可以利用新的接口,而旧的用户则不会产生影响,其代码可以不经修改,不经重新编译,正常运行。用户通过CAR构件方式实现的程序,都可以通过命名服务机制的方式,提供给其它远程用户。
3、从安全性来看,用户可以通过将一个信任度不高的服务启动在一个单独的进程中,并通过命名服务机制获得,这样就通过进程地址空间机制,隔离了服务与用户,同时服务之间的数据交换可以经过系统的构件平台数据交互机制的检测。
4、命名服务机制允许将系统提供的各种服务接口,比如进程,线程,module,同步对象等与对应的字符串绑定,其它进程可以通过命名服务机制非常方便的获得该进程,从而能很方便的实现进程间通讯,扩展了系统的功能。
综上所述,命名服务机制以简单的三个API函数,提供对服务组件和字符串的绑定,到获取,到注销的整套机制,用非常简约而且容易理解的方式提供给用户。
最后所应说明的是,以上实施例仅用以说明本发明的技术方案而非限制,尽管参照较佳实施例对本发明进行了详细说明,本领域的普通技术人员应当理解,可以对本发明的技术方案进行修改或者等同替换,而不脱离本发明技术方案的精神和范围,其均应涵盖在本发明的权利要求范围当中。
权利要求
1.一种命名服务机制,其特征在于包括以下步骤步骤1、服务端进程获得一个组件对象的指针;步骤2、服务端进程将获得的组件对象的指针与一个字符串绑定,并注册到内核,获得组件对象在内核的注册信息对象,内核创建一个代表命名服务的命名服务对象,并将命名服务对象以所述字符串为标志与注册信息对象绑定;步骤3、客户端进程利用所述字符串查询获得所述命名服务对象;步骤4、客户端进程找到绑定的所述字符串对应的注册信息对象;步骤5、客户端进程通过所述注册信息对象和字符串找到组件对象的指针。
2.根据权利要求1所述的命名服务机制,其特征在于所述步骤5之后还具有以下步骤步骤6、客户端进程利用所获得的组件对象的接口指针调用组件方法;步骤7、客户端进程释放所述组件对象接口指针,通知服务端进程。
3.根据权利要求2所述的命名服务机制,其特征在于所述步骤7之后还具有以下步骤步骤8、服务端进程注销所述命名服务对象;步骤9、服务端进程释放所述组件对象的接口指针。
4.根据权利要求3所述的命名服务机制,其特征在于所述步骤9之后,如果客户利用所述字符串从内核获得所述组件接口指针,将无法获得,并且返回错误。
5.根据权利要求4所述的命名服务机制,其特征在于所述步骤1中组件对象的指针为本地组件指针;所述步骤2获得组件对象在内核的注册信息对象具体为服务端进程通过本地组件指针,找到或者创建存根对象,生成和所述存根对象相关联的注册信息对象。
6.根据权利要求4所述的命名服务机制,其特征在于所述步骤1中组件对象的指针为远程组件指针,所述远程组件指针与存根对象以及内核中一个注册信息对象唯一对应;所述步骤2获得组件对象在内核的注册信息对象具体为根据所述远程组件指针与其唯一对应的关系找到注册信息对象。
全文摘要
本发明涉及一种命名服务机制,包括以下步骤步骤1服务端进程获得一个组件对象指针;步骤2服务端进程将获得的组件对象指针与一个字符串绑定,并注册到内核,获得组件对象在内核的注册信息对象,内核创建一个代表命名服务的命名服务对象,并将命名服务对象以所述字符串为标志与注册信息对象绑定;步骤3客户端进程利用所述字符串查询获得所述命名服务对象;步骤4客户端进程找到绑定的所述字符串对应的注册信息对象;步骤5客户端进程通过所述注册信息对象和字符串找到组件对象的指针。因此本发明可以支持远程接口代理,实现字符串与对象的绑定,且允许将任意接口代理与字符串绑定。
文档编号G06F9/44GK1971508SQ20061011898
公开日2007年5月30日 申请日期2006年12月1日 优先权日2006年12月1日
发明者苏翼鹏, 刘亚东, 梁宇洲, 陈榕, 王晨辉 申请人:上海科泰世纪科技有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1