本发明要求了Todorov等人的临时申请系列号60/232731的优先权,它在2000年9月15日被提交,名称为“远程多客户协议支持(Remote Multiple Client Protocol Support)”,这里特别包合了其内容,对其进行整体引用,也包含了其引用的任何内容和思想。
具体实施方式
如这里先前所提到的,就结合新的客户数据交换协议(例如,DDE/SuiteLinK/OPC)来说示例性数据访问服务器结构是可扩展的。可扩展性由一个使用诸如插件这样的模块化程序扩展的数据访问服务器结构实现。模块化程序扩展向一个执行对应于接口调用的一组操作的数据访问服务器引擎发出接口调用。模块化程序扩展将根据特定数据交换协议从客户应用程序接收到的请求传送给使用接口调用的数据访问服务器引擎。每个模块化扩展独立于其他模块化程序扩展存在。每个模块化程序扩展运行时在功能上与数据访问服务器引擎连接/可连接(不需要编程)。在过程控制系统/网络中配置了服务器后,通过程序/系统数据交换协议扩展的模块性能以及数据访问服务器的可扩展结构可以扩展由数据访问服务器支持的客户数据交换协议集。
转到图1,说明性地描述了一个过程控制网络10的示例性部分。过程控制网络10可被看作连接到一个或多个与过程控制网络10的特定层有关的网络链接的设备集。在示例性实施方式中,过程控制网络10中描述出的部分包括一个域总线层12、一个本地控制层14以及一个管理控制层16。虽然示例性实施方式被描述为具有三层,本领域技术熟练者将容易欣赏到本发明可应用到具有更多、更少或相同网络层数的多种过程控制网络结构。所描述出的说明性的网络10体现了一个多层总线拓扑。但是,本发明可结合到一个实现其他网络拓扑(如星形网络、总线/星形混合网络等)的过程控制网络中。
在过程控制网络的示例性部分中,一组智能域设备集20位于域总线层12。域设备包括感知受控工业过程中的压力、温度、液体流量等的智能过程变量发射机。域设备还包括调节器,如那些能够使池、燃烧室等中的液体流量阀门打开和关闭的调节器。
本地控制层14的一个或多个控制处理机30根据智能域设备集20执行本地控制功能。控制处理机30接收智能域设备20提供的过程状态信息。状态信息包括压力、温度、质量流量、容积流量等。控制处理机将接收到的状态信息加到过程的所需设定点上,然后向调节器发送控制信息,以便获取或保持所需要的设定点。控制处理机被编程/配置为存储与其控制功能有关的状态和控制信息。
管理控制层16包括帮助和/或实现做出企业/工厂层决策和管理(如,设定点)控制值指定功能的高层控制应用程序。一个告警服务器40接收来自多个低层源,包括控制处理机30和域设备的过程状态数据。告警服务器40比较接收到的状态数据与告警/事件条件集,并响应检测到的告警/事件条件向监控器或控制处理机(如控制处理机30)发布相应的通知。控制处理机30向受控域设备/调节器发布相应的信号以处理事件/告警条件。一个同样在管理控制层16运行的历史记录机42将从过程控制系统的上述任何层接收到的数据归档。这种数据能被多个应用程序审查和验证。一个人机接口(HMI)44是另一个连接到管理控制层16的节点。人机接口44提供图形/文本用户功能集,使得人类可以查看关于与图1所描述的项目有关的过程控制系统的受控过程的操作/状态。
在本发明一个示例性实施方式中,数据访问服务器50介于过程控制系统的管理控制层16的处理节点和低层(如本地控制层14和场总线层12)之间。数据访问服务器50从域设备20(通过信道52)和/或控制处理机30(通过信道54)接收和/或提取数据,并将相应的(可能已经重新设置了格式)数据提供给过程控制网络10的管理控制层16的处理节点。数据访问服务器50执行向多个客户应用程序提供数据的任务,其中客户应用程序根据特定数据交换协议获取数据,否则不能访问在本地控制层14和域总线层12提供的过程控制数据。当新的客户应用程序使用新开发的数据交换协议,或者目前不被数据访问服务器50支持的现有数据交换协议时,保持数据访问服务器50向新的管理层客户应用程序提供过程控制/制造数据的能力可能是一个不小的、成本很高的任务。
但是,结合了本发明的数据访问服务器50提供了一个可扩展的客户接口结构,它引入了DAS50的扩展,以支持附加的数据交换协议,即使数据访问服务器50已配置在了过程控制网络中。这样的附加协议支持是通过结合模块化程序/系统扩展(如插件)来实现的,该模块化程序/系统扩展支持符合添加到在网络10的管理控制层16运行的应用程序集的新客户应用程序的数据访问要求的特定数据交换协议。在本发明的一个示例性实施方式中(下面参照图3进行了说明),数据访问服务器50中的一个库将激活模块化程序/系统扩展。激活的扩展通过访问由数据访问服务器50中的一个引擎执行的应用程序接口集支持的核心数据访问服务器功能来执行客户应用程序。
安装数据交换协议扩展模块的过程可在数据访问服务器50的使用期限的任何时刻进行,包括最初安装了数据访问服务器50后。当升级到支持新客户应用程序版本的附加数据交换协议(如OPC的新版本)时,不需要安装新版本数据访问服务器50。而是由先前安装的数据访问服务器50软件的开发者/维护者新建一个支持新的OPC数据交换协议的客户协议插件。然后新的OPC插件被添加到现有的结合了可扩展的、基于插件的数据访问服务器结构的数据访问服务器中。
另外,注意到本发明不限于任何特定的过程控制系统网络拓扑或技术。例如,所发布的示例性过程控制网络包括一个分级配置的数字系统。但是,在一个替换网络实施方式中,本发明被结合到一个连接到单层过程控制网络的DAS中,该网络的域设备、控制处理机、管理控制应用程序组成单条总线上的节点。在另一种情况中,DAS接收关于使用过程通信的4-20毫安标准的常规模拟域设备的数据。
转到图2,示意性地描述了数据访问服务器50的一般接口配置。在数据源一侧,数据访问服务器50通过特定制造商数据输入逻辑58从诸如域设备20或过程控制器30这样的物理设备56获取数据。结合到特定制造商数据输入逻辑的特定制造商数据访问协议的例子为DF1和Allen Bradley PLC的可编程控制器控制命令(PCCC)。数据访问服务器50将获取的数据转换为一般的格式,并将转化后的数据存储在数据访问服务器50保持的一个数据库中。响应特定的客户请求,数据访问服务器从数据库取出数据,并根据与向客户60、62和64传输数据所需的各个不同的客户数据交换协议有关的特定客户应用程序数据交换协议传输数据。在本发明的一个示例性实施方式中,三个结合在数据访问服务器50中的特定协议的插件支持通过三个不同的数据交换协议(DDE、Suite Logic和OPC)向客户60、62和64提供过程控制数据访问。结合在DAS50中的特定数据交换协议的插件分别为客户60、62和64的数据访问产生DDE接口70、SuiteLink接口72和OPC2.0接口74。
转到图3,示意性地描述了结合本发明的一个数据访问服务器的软件结构。如图3所示,结合本发明的一个数据访问服务器的结构包括,例如,三个不同的功能组件。一个客户数据交换组件80负责接收客户应用程序请求并根据所支持的特定数据交换协议将响应数据提出给客户应用程序。一个数据访问服务器(DAS)引擎90组件根据由客户应用程序请求发起的来自客户协议组件80的先前的请求向客户协议组件80提出全局数据。DAS引擎90还与设备协议组件96接口。设备协议组件96负责将从诸如域设备和控制处理机这样的数据源接收的数据发送到DAS引擎90。然后DAS引擎90将接收到的数据传递回到客户协议组件80的一个特定的协议模块或者存储接收到的数据,等待由客户应用程序请求的由DAS50通过客户数据交换协议组件80接收到的以后的请求或更新。
如前所述,客户数据交换协议组件80有助于根据DAS50当前支持的特定数据交换协议向客户应用程序提供数据。如图3所示,客户数据交换协议组件80结合了一个模块结构。尤其地,客户数据交换协议组件80包括一组可扩展的客户数据交换协议模块集(如插件84、86和88),该模块集支持DAS50和一组根据特定数据交换协议与DAS50通信的客户应用程序集之间的特定数据交换协议的交互。这种数据交换协议包括,例如,DDE、OPC2.0、和SuiteLink。这三种数据交换协议的每一个分别由安装于并同时激活在DAS50上的DDE插件84、OPC2.0插件86和SL插件88处理。
插件84、86和88通过一个结合在插件84、86和88以及DAS引擎90中的标准接口集(下文中参照图8和9说明)与DAS引擎90交互。一个标准接口集82(参见图9)包括任何一个插件可能需要的接口操作集,以使得DAS引擎90能够响应由插件从在过程控制系统的管理控制层执行的客户应用程序接收的请求。插件和DAS引擎90之间的标准化接口还有助于在不影响插件与替换DAS引擎90的兼容性的情况下替换DAS引擎90。
数据交换协议组件80的插件虽然遵循由DAS引擎90提供的特定接口,但却是以多种方法产生的。客户数据交换协议层80的插件可随意写成。但是,在本发明的一个实施方式中,插件是由一个工具包生成的,该工具包包括结合在DAS引擎90中的包括对标准接口的调用的插件的部分指定的接口程序。特定协议编程完成每个对应于特定数据交换协议的插件。
数据交换协议组件80的特定协议插件使得数据访问服务器50能够将DAS 50接收的从过程控制系统中的域设备和控制处理机生成的数据,根据客户应用程序所使用的特定数据交换协议的语言、方法和要求提供给客户应用程序。从而,数据交换协议组件80有助于为利用过程控制系统处理机和域设备提供的信息的客户应用程序建立特定数据交换协议接口。客户应用程序反过来可以利用接收到的信息实现对工业/制造过程的管理控制。
当然,仅当数据交换协议组件80支持特定客户应用程序使用的数据交换协议时,DAS50才能接收数据请求并向特定客户应用程序提供信息。在本发明的说明性实施方式中,这种特定协议支持是由一个安装在DAS50上的通过标准接口集82与DAS引擎90提供的核心功能接口的数据交换协议插件提供的。因此,如果一个新的客户应用程序使用目前安装DAS50上的插件不支持的数据交换协议,则一个新的插件被安装在数据交换协议组件80处。如果当前一个特定数据交换协议不存在插件,则为以前不支持的数据交换协议开发新的插件。
所发布的DAS结构有助于使得增加DAS50以结合一个以前不支持的由新的客户应用程序所使用的数据交换协议对现有的DAS50程序的影响最小。新插件由系统管理员通过使用几个已熟知的安装程序中的任何一个在不修改现有DAS50程序的情况下安装在DAS50上。通过安装新插件扩展DAS50能力以支持新的客户应用程序数据交换协议,不需要重新开发DAS50软件,也不需要重写现有DAS50软件的局部。从而,图3所示的DAS50尤其是数据交换协议组件80的结构,减少了增加和/或升级由配置在一个过程控制网络/系统中的DAS50所支持的当前数据交换集所需要的劳动力。
在本发明的一个实施方式中,DAS50的实现是部分基于熟知的MICROSOFT公司的COM/DCOM技术的。为覆盖尽可能多的客户应用程序数据交换协议,数据访问服务器50既支持动态插件也支持静态插件。动态插件是一类封装了客户协议的插件(如OPC),其中服务器能够被客户应用程序请求(由动态插件接收)所激活。通常这样的插件的客户通过一个服务控制管理器(SCM)激活服务器(在这里是DAS50),被激活的服务器的生存期由客户参考计数所决定。当DAS的客户参考计数达到0时,服务器关闭或进入某种形式的非活动状态(至少对于该特定插件部分)。另一方面,静态插件是一类旨在与不具有服务器激活设备(如DDE和SuiteLind数据交换协议客户应用程序)的客户通信并预期数据访问服务器在客户试图与数据访问服务器连接和通信时被激活的插件。本发明的实施方式包括静态和动态插件中的一种或两种。
所发布的数据访问服务器结构的可扩展数据交换协议接口有助于实现在DAS引擎90中实现的数据访问服务器的核心组件的独立开发/修改,以及实现在特定协议插件中实现的数据交换协议的开发/结合。如果在完成数据访问服务器50的开发和配置后需要支持新的客户应用程序数据交换协议,则对新协议的支持是通过开发和安装一个根据标准接口集82的接口要求开发的新的特定协议插件来建立的。从而,数据访问服务器50的配置不会由于需要建立对新的或目前不支持的数据交换协议而一直继续。下文说明的图4描述了当新的数据交换协议插件被安装在执行数据访问服务器50的网络节点上时,在数据访问服务器50上执行的事件序列。此后,图5和6描述了实现了所发布的包括插件形式的客户协议扩展模块的可扩展数据访问服务器结构的一个数据访问服务器的激活和关闭过程中的事件序列及执行它们的实体。
DAS引擎90逻辑地组织从设备接收到的数据以便通过标准接口集82向插件(如DDE插件84)提供一个标准/普通数据访问接口。如上文所说明的,数据交换协议组件80的插件,提供对接收到的数据的特定客户协议访问。从而,DAS引擎90与被修改以兼容先前不支持的数据交换协议的数据交换协议组件80相比保持相对稳定(不修改DAS引擎90)。
在DAS引擎90处以标准方式(不论发出请求的客户的协议如何)执行响应一个特定客户协议插件所指定的请求的数据激活或对存储数据的实际取出。在本发明的一个实施方式中,特定客户协议插件根据特定数据交换协议接收所需项目的数据请求,并将请求转化成一个或多个对与标准接口集82有关的特定操作的调用。调用被DAS引擎90中的核心数据访问功能处理。DAS引擎90向设备协议发出相应的请求(或者取出已由设备协议提供的数据)。如果需要,设备请求从过程控制系统中的数据源(如,域设备和控制处理机)取出被请求的数据。DAS引擎90通过结合在DAS引擎到插件接口中的标准接口插件操作返回数据(参见图8和图9)。
DAS引擎90软件管理群组以及群组涉及的项目。一般地,一个群组是项目或者可能是其他具有相似要求的群组(在嵌套配置中)的集合。一个项目代表/对应于数据访问服务器50上的一个数据源。DAS引擎90还管理群组和项目的等级层次一低层端点为单个物理项目(如,诸如可编程逻辑控制器这样的数据供应设备中的一个对象)。DAS引擎90支持群组与特定涉及的项目之间的n到1关系。从而,DAS引擎90最优化了对项目的访问,以便如果多个(n)客户/群组访问/涉及一个相同的数据项,则DAS引擎90只获取数据项一次,然后将数据提供给多个(n)请求者-有可能根据所支持的多个数据交换协议。在本发明的一个特定实施方式中,DAS引擎90将取出的一个数据值存储为一个物理项,所有涉及该数据项的客户(群组项)使用所存储的物理项的属性。每个物理项保持/提供一个相应数据项的当前值、时间戳和质量(VTQ)。每个群组项存储群组项接收到的所涉及项目的最新更新的值和质量。在取出了对应于一个所涉及的物理项的被请求的特定数据后,DAS引擎90访问数据交换协议组件80中所包含的数据交换协议插件之一,以根据一个特定数据交换协议将所涉及的项目的数据提供给一个客户应用程序。
数据访问服务器50的软件结构的最低层是设备协议组件(或“服务器特定部分”)96。设备协议组件96实现硬件(还可能是数据库)协议,以便将实际数据从域设备20和控制处理机30发送到DAS引擎90。设备协议组件96实现一个或多个不同的数据提取接口标准,以便从过程控制系统/网络环境中的多个域设备和控制处理机中获取过程控制信息。
最后,尽管在图3中没有特别描述,但DAS50包括一个支持功能库,包括与WINDWOS操作系统的COM/DCOM组件有关的标准支持功能。这些支持功能有助于图3中所描述的DAS50的组件的启动和关闭。这些支持功能的操作在下文中联系DAS50执行的示例性方法说明。
现转到图4,描述了通过插件将一个新的客户协议添加到数据访问服务器50的步骤集。插件本身包括一个或多个在配置时复制到目标服务器系统上的软件模块(如dll或exe文件)。例如,DAS50是一个执行Wonderware的数据访问服务器软件的计算节点。在本例中,插件被打包在一个可由管理员执行的自安装程序/实用程序中。增加过程在高层处理,不需要用人工编程技能完成。在步骤100,一位系统工程师启动一个熟知的设计的安装程序,该设计在步骤102中生成一个窗口(或一系列窗口),窗口上给出与特定客户协议插件有关的自定义选项集。在步骤104中,插件软件模块被配置在DAS50上(以及其他任何执行插件软件的计算设备上)。
接下来,在步骤106中,调用注册命令,以根据插件软件配置其上的特定操作环境/系统的要求来注册插件软件。正如本领域技术熟练者将欣赏的那样,根据不同系统的通知要求,不同系统间的这些要求是不同的。在本发明的一个示例性实施方式中,插件注册在一个插件库中。在示例性实施方式中,使用WINDWOS“组件类别”机制在MICROSOFT WINDOW环境中实现插件库。在WINDOWS环境中,组件类别机制采用WINDOWS注册表作为标识的注册协议扩展插件的存储区域。通过这种注册配置,既可以对逻辑上相关的组件进行分组,还可以用使用该插件的客户应用程序枚举注册组件。在协议启用步骤108中,执行步骤以使得使用启用的特定客户数据交换协议的客户应用程序能够看到启用插件的DAS50。例如,在OPC客户的情况下,DAS50注册在WINDOWS注册表的OPC类别中。步骤108建立了客户应用程序和注册插件中实现的特定客户访问协议间的链接。在协议启用步骤108中,DAS50激活注册的协议插件根据特定客户协议促进与发出请求的客户的交互的能力。此后,启用的插件作为协议接口运行在DAS50存储的过程数据和使用启用的插件中包含的数据传输协议的发出请求的客户之间。虽然在示例性实施方式中使用了WINDOWS注册表,但是在本发明的替换实施方式中插件或其他扩展模块的注册可通过其他注册库产生。
在说明了客户协议插件如何添加到现有系统后,注意力转到图5,一个概括性的步骤集描述了DAS50如何被激活/初始化,在这个特定的例子中是与一个OPC客户请求有关的。在特定例子中,响应初始客户请求使用MICROSOFT WINDOWS SCM实用程序动态激活DAS50。但是,在本发明的替换实施方式中,DAS50和/或客户协议特定插件是在接收到来自客户应用程序的特定请求之前静态激活的。在初始启动过程中DAS50被激活,并确立支持数据交换协议组件80和DAS引擎90的客户数据交换协议插件之间的连接的对象和数据结构。特别地,在驻留DAS50的所有插件的DAS引擎90的激活过程中,访问所安装的插件库(如,WINDDOWS注册表内)并激活所安装的客户协议插件。在激活过程中,DAS引擎90执行一个步骤序列,以便根据基于MICROSOFT的COM(组件对象模型)的技术激活安装的每个动态激活的插件。从而,从DAS50的客户的观点来看,DAS50(及其被激活的协议插件)对客户应用程序来说是执行特定客户使用的特定客户协议的单个实体。实际中,DAS50是一个多组件系统,它具有多个客户接口组件(如插件),为DAS50提供了扩展其所支持的客户协议接口集,以便向多个实践多种不同的数据交换协议的不同客户提供数据。要强调的是这些步骤是示例性的,本领域技术熟练者将乐意欣赏在本发明的替换实施方式中修改DAS50及其安装的插件的启动步骤。
在步骤200中,一个OPC客户请求(来自任何通过OPC协议与DAS50接口的应用程序)调用“CoCreateInstance”WINDOWS API。随后的步骤创建一个图3中所表现的类型的完整功能数据访问服务器,它包括客户数据交换协议插件集84、86和88,DAS引擎90和设备协议组件96,以及使得这些组件能够在DAS50中彼此间传递请求和数据的结构。CoCreateInstance API被调用一次,以启用一个DA服务器可执行文件。由于在本发明的一个首选实施方式中,DA服务器的单个可执行实例支持多个到标识的DA服务器的不同连接上的(并且可能使用不同的数据交换协议)多个客户请求,因此启动可执行文本的附加复本不但没必要还有可能降低DAS50的性能。
响应CoCreateInstance调用,在步骤202中WINDWOS操作系统的一个系统控制管理器(SCM)发起一个“CreateInstance”WINDOWS API调用,以创建一个IOS_Activate_Class_Factory对象实例。接下来,在步骤204中,IOS_ActivateClassFactory创建一个IOS_Server对象。此操作仅发生一次(在DAS的初始启动中)。IOS_Server对象是从一个为特定设备协议组件96行为编写的特定设备协议DLL创建的逻辑实体。IOS_Server对象支持DAS引擎90和DAS50的设备协议组件96之间的交互。在步骤204中创建IOS_Server对象后,在步骤206中IOS_Server对象调用IOT_Server对象的创建。从一个标准DAS引擎DLL生成的IOT_Server对象,建立了支持DAS引擎90和数据交换协议组件80(包括相应于特定数据交换协议的插件(如OPC))以及DAS50的设备协议组件96之间的交互的连接。
在步骤208中,IOS_ActivateClassFactory初始化在步骤204中创建的IOS_Server对象实例。步骤208中的初始化包括传递使DAS引擎90和设备协议组件96能够通信的信息。在步骤210中,IOS_Server建立桥对象,根据设备协议组件96支持的规范修改DAS引擎90的缺省行为(显示出的对象和功能群组)。在步骤212和213,IOS_Server对象和IOT_Server对象交叉初始化桥对象,以便IOS_Server对象和IOT_Server对象均能引用桥对象。
在步骤214中,IOT_Server标识所有安装在运行DAS50的计算机上的插件。在步骤214中标识插件后,在步骤216中,IOT_Server对象调用指定一个插件(如OPC插件)的CoCreateInstance API。API调用导致根据所指定的(如OPC)插件初始化PluginCreator插件。步骤214和216对所有插件重复。完成步骤214和216后(有可能对于所支持的多个客户数据交换协议而进行多次重复),DAS90已准备好处理来自客户应用程序的请求-包括在执行步骤200至216时产生的一个第一客户请求。
图5的剩余步骤是关于创建一个特定客户连接的逻辑数据访问(DA)服务器对象。这些剩余步骤只用于基于COM的客户(如OPC)。在非COM客户情况下,特定数据交换协议的插件处理客户连接服务器对象的创建。在步骤218中,SCM调用IOS_Activate_ClassFactory对象上的CreateInstance操作,以初始化对应于特定客户-服务器连接的逻辑DA服务器对象的创建。在步骤220中,DAS50的IOS_Activate_ClassFactory对象创建一个IOS_Activate对象以便为创建来服务新的客户应用程序/DA服务器连接的逻辑DA服务器对象实例建立一个标识。在步骤222中,IOS_Activate_ClassFactory对象将DA服务器的实例计数从0增加为1。实例计数代表DA服务器的当前用户数目。当实例计数为0时,DA服务器实例被删除。
此后,步骤224、226、228和230中的调用集传递调用,在便为特定客户连接创建新的逻辑DA服务器对象。在步骤224中,IOS_Activate_Class_Factory调用IOS_Activate对象上的为接口(逻辑DA服务器实例)指定标识的QueryInterface方法。在步骤226中,IOS_Activate用标识的接口调用IOS_Server对象上的SystemQueryInterface方法。在步骤228和230中,传递建立客户应用程序和DAS 50之间的特定逻辑接口的请求以建立一个逻辑DA服务器对象时,IOS_Server对象将接口标识传递给IOT_Server对象,IOT_Server对象将接口标识传递给PlugInCreator。
在步骤232中,PlugInCreator在现有DA服务器对象实例集中查找标识的DA服务器对象实例。如果存在DA服务器对象实例,则来自基于COM的客户(如OPC)的请求被指派给DA服务器对象。否则,在步骤234中为特定客户连接创建逻辑DA服务器对象实例。
现参见图6,描述了当一个客户应用程序释放一个逻辑DA服务器对象实例集中的最后一个实例时关闭DAS50的步骤集。注意到之前的例子是关于一个基于COM(如OTC)的插件连接的。在非COM插件的情况下,由插件本身进行关闭。由于可能有多个插件和多个客户同时连接到DAS50,在顺序关闭中,DAS50确保在关闭其本身之前断开所有连接的服务器。图6描述的步骤说明了通过为每个连接的客户执行握手程序执行顺序关闭的示例性方法。在步骤300中,一个客户应用程序通过调用相应的IOS_Activate对象关闭与DAS50的连接-DAS50目前服务的连接中的最后一个。作为响应,在步骤302中,与客户连接有关的IOS_Activate对象开始删除与连接有关的DA服务器。在步骤304和306中,对象删除和程序清除通过在图5中概括的步骤中创建的IOS_Server和IOT_Server向PlugInCreator级联。在步骤308中,PlugInCreator查找关于与断开的客户有关的数据交换协议的对象。在步骤310中,PlugInCreator调用DA服务器对象上相应于客户连接的释放方法,在步骤312中DA服务器对象被销毁。
如上文所说明的,当所有连接被关闭后,DAS50本身关闭。在步骤320中,连接的对象计数减1。假设当前连接是DAS50的最后连接,对象计数达到0,即没有连接。在步骤322中IOS_Activate对象调用IOS_server对象上的suggestshutdown方法。IOS_server将调用传递到IOT_server对象上。IOT_server以IsShutdownPossible方法调用的形式将关闭请求传递给PlugInCreator对象。如果关闭确实可能,则在步骤328中IOT_server对象调用PlugIn中心上的释放方法。然后PlugIn中心关闭客户用于所关闭的连接的特定数据交换协议的插件。最后,在步骤332中,IOT服务器清除创建来支持DAS50及其集成的客户和设备接口协议组件的临时结构。
现转到图7,概括了DAS50响应一个客户应用程序请求的示例性步骤集。同样,请求是基于COM(如OPC)的客户应用程序。但是,不基于COM的客户应用程序被认为属于本发明的范围之内。对于非COM应用程序过程步骤可能不同。在步骤400中,OPC客户发出请求,调用图5中描述所有或部分步骤(取决于这是否DAS50的第一个客户连接)以便创建连接的一个DA服务器对象。一旦被激活,DAS50通过插件接收来自客户应用程序的请求。然后请求从适当插件通过下文参考图9说明的标准接口操作调用传递到DAS引擎90。在DAS50建立起适当的DA服务器对象以支持到客户的连接后,在步骤402中客户调用插件上的AddGroup功能,以建立一个容器,在其中存储/访问客户所请求的过程控制数据。在步骤404中,AddGroup请求被插件(如OPC插件86)通过标准接口操作“AddGroup”传递到DAS引擎90。在步骤406中,客户应用程序对于所添加的群组中的被标识的数据的更改请求预订服务,在步骤408中预订请求被传递到DAS引擎90。接下来,在步骤410中,客户应用程序请求插件将特定数据项(如压力传感器读数)添加到在步骤402中添加的群组中。在步骤412中插件将请求传递到DAS引擎90。
此后,在步骤414中DAS引擎90通过向设备协议组件的请求获取被请求的数据。在步骤416中,设备协议组件96执行请求,以便使用特定设备协议从域设备数据提供者(包括控制处理机)请求数据来获取数据。在步骤418中,相应于被请求的数据项的设备数据被域设备数据提供者提供给设备协议组件。在步骤420中,设备协议组件96将设备数据返回给DAS引擎90。接下来,在步骤422中,DAS引擎90将设备数据提供给适当的插件。插件执行消除未变化的数据所需的数据变化过滤,并在步骤424中将变化的数据转发。
注意到对于图7中描述的步骤序列,DAS(OPC)插件垂直线左侧的步骤是根据一个客户应用程序数据交换协议(如OPC2.0)执行的。特定客户应用程序协议插件(如OPC插件86)根据特定数据交换协议与客户通信。DAS插件垂直线右侧的步骤是根据为所有插件和DAS引擎90通用定义的接口(操作)集执行的一参见下文说明的图8和9。从而,DAS插件充当特定客户应用程序协议和DAS引擎90之间的协议转换器。
说明了实现本发明的一个示例性数据访问服务器结构后,以下观察是对于服务器的模块客户协议接口结构作出的。首先,特定设备数据的编码与客户应用程序数据交换协议是分离的。因此,开发数据访问服务器的两个不同方面是自动的。第二,使数据访问服务器50与采用支持插件的数据交换协议之一的客户应用程序接口不需要特别的客户应用程序协议配置。假定特定数据交换协议的插件存在,则系统管理员通过常规方式获取和安装插件。不需要更新DAS的核心功能—它是保持不变的。第三,支持“动态”插件(对于基于COM的客户)和“静态”插件(对于不基于COM的客户)。静态插件不会激活DAS(即DAS必须独立于插件启动)。在出现静态插件的情况下,提供DAS控制客户以便用户能够在调用静态插件处理客户数据请求前启动DAS。动态插件激活相关的服务器软件,当服务器的客户引用计数达到0时服务器关闭。第四,通过本发明,可以对结合了初始安装之后添加的插件的服务器库的现有数据访问服务器进行平衡(即提供现成的平台),以便通过新的数据交换协议与新的客户应用程序接口。
在本发明的一个实施方式中,开发插件时,插件是过程中组件(如,动态链接库(DLL))。但是,在本发明的一个替换实施方式中,插件被开发为数据访问服务器50的过程外组件(如*.exe)。关于线程,DAS引擎90被开发为多线程单元(MTA)。如果采用MTA,则避免了proxy/stub对(这减慢了性能)。对于封装了基于COM的协议的插件,插件为MTA,以确保遵循IUnknown标识的COM规则(MICROSOFT COM规范的一部分)。从而,每当COM对象为请求者时,它返回相同的接口以提供其IUnknow接口。对于其他接口没有此要求。关于粒度,数据交换协议插件处理宽范围的与取出数据有关的对象,包括服务器和群组对象。服务器对象给出全球服务器服务。服务器还被指定为涉及其他群组对象或特定数据项的群组对象的容器。
在本发明的一个实施方式中,插件和DAS引擎90之间的接口是基于COM接口的。下文说明图8中所标识的由插件所执行和由DAS引擎90所调用的接口操作的结构和内容。通过由DAS引擎90调用的和由所安装的不同插件执行的操作,DAS引擎90可与客户应用程序通过插件进行过程数据通信。虽然下文标识和说明了接口操作及其相关操作的基本集合,但应理解对于本领域技术熟练者,本发明的替换实施方式包括不同的接口操作和规范。
DAS引擎90到插件的接口以以下方式说明。首先,一个接口“声明(Declaration)”标识与该接口有关的操作集。接下来,声明部分标识的操作在以“操作(Operations)”为标题而标识出的子部分中单独说明。插件所执行的操作是联系所传递的示例性的参数和插件执行的一般功能说明的。
一个IioPiData接口500包括一个操作集,它被DAS引擎90调用,在插件内执行,是关于从DAS引擎90到数据交换协议的通知(包括数据),该通知是关于从一个被DAS引擎90管理/监控的过程数据源读出数据和向其写入数据,以便过程数据能够被DAS引擎90通过设备协议96访问。以下是IioPiData接口500的声明/概要示例。
Declaration
[
object,
uuid(7AA39773-AC55-11D2-8203-00A024A866AC),
helpstring(″IIoPiData Interface″),
pointer_default(unigue)
]
interface IIoPiData:IUnknown
{
HRESULT OnData(
[in] PIHANDLE hGroup,
[in] DWORD dwCount,
[in,size_is(dwCount)]PIHANDLE * phPlugInItems,
[in,size_is(dwCount)]VARIANT * pvValues,
[in,size_is(dwCount)]WORD * pwQualities,
[in,size_is(dwCount)]FILETIME * pftTimeStamps,
<!-- SIPO <DP n="20"> -->
<dp n="d20"/>
[in,size_is(dwCount)]HRESULT * pErrors,
[out]UPDATECODE * updatecode
);
HRESULT OnReadComplete(
[in] DWORD dwCount,
[in,size_is(dwCount)]PIHANDLE * phPlugInItems,
[in,size_is(dwCount)]VARIANT * pvValues,
[in,size_is(dwCount)]WORD * pwQualities,
[in,size_is(dwCount)]FILETIME * pftTimeStamps,
[in,size_is(dwCount)]HRESULT * PErrors,
[in]CTTRANSACTIONDEF TransactionDef
);
HRHSULT OnWriteComplete(
[in]DWORD dwCount,
[in,size_is(dwCount)]PIHANDLE * phPlugInItems,
[in,size_is(dwCount)]HRESULT * pErrors,
[in]CTTRANSACTIONDEF TransactionDef
以下是对在一个特定数据交换协议插件中实现IioPiData接口500的示例性操作的说明。
Operations
OnData
Declaration
HRESULT OnData(
[in]PIHANDLE hGroup,
[in]DWORD dwCoun,
[in,size_is(dwCount)]PIHANDLE * phPlugInItems,
[in,size_is(dwCount)]VARIANT * pvValues,
[in,size_is(dwCount)]WORD * pwQualities,
[in,size_is(dwCount)]FILETIME * pftTimeStamps,
[in,size_is(dwCount)] HRESULT * pErrors,
[out]UPDATECODE * updatecode
)
OnData操作的参数说明
Hgroup |
标识插件提供的项目所属的群组的句柄。 |
DwCount |
传递的数组的大小.这是此次扫描报告其VTQ的项目的数目。 |
phPlugInItems |
dwCount句柄的数组.这些句柄由插件提供,并标识其VTQ被报告的项目。注意:在处理数组时由插件负责为其分配内存. |
PvValues |
dwCount变量值的数组.这是被报告的项目的值。注意:在处理数组时由插件负责为其分配内存。 |
pwQualities |
dwCount DWORD的数组。这是被报告的项目的质量。注意:在处理数组时由插件负责为其分配内存。 |
pftTimeStamps |
dwCount FILETIME结构体数组。这是被报告的项目的时间。注意:在处理数组时由插件负责为其分配内存。 |
Perrors |
HRESULT的数组。这是每个被报告的项目的独立错误代码。插件可使用比特15(0x00008000)检查首要更新。在将pError值传递到OPC客户前先用-0x00008000掩码。注意:在处理数组时由插件负责为其分配内存。 |
备注:
对于活动项目,当特定服务器协议引擎(在DAS50的设备协议层96处)确定某项目具有新值时,该项目被添加到列表。在协议周期末尾(由协议引擎确定),新项目VTQ的列表被DAS引擎90通过此方法发送到特定数据交换协议插件。由DAS引擎90确定值的实际变化。只有那些接收了新更新的值的项目才被放进列表中。
OnReadComplete
Declaration
HRESULT OnReadComplete(
[in]DWORD dwCount,
[in,size_is(dwCount)]PIHANDLE * phPlugInItems,
[in,size_is(dwCount)]VARIANT * pvValues,
[in,size_is(dwCount)]WORD * pwQualities,
[in,size_is(dwCount)]FILETIME * pftTimeStamps,
[in,size_is(dwCount)]HRESULT * pErrors,
[in]CTTRANSACTIONDEF TransactionDef
)
OnReadComplete操作的参数说明:
DwCount |
传递的数组的大小。这是其请求读取已完成且正在报告VTQ的项目的数目。 |
phPlugInItems |
dwCount句柄的数组。这些句柄由插件提供,并标识其VTQ被报告的项目。注意:在处理数组时由插件负责为其分配内存。 |
PvValues |
dwCount变量值的数组。这是被报告的项目的值。注意:在处理数组时由插件负责为其分配内存。 |
pwQualities |
dwCount DWORD的数组。这是被报告的项目的质量。注意:在处理数组时由插件负责为其分配内存。 |
pftTimeStamps |
dwCount FILETIME结构体数组。这是被报告的项目的时间。注意:在处理数组时由插件负责为其分配内存。 |
pErrors |
HRESULT的数组。这是每个被报告的项目的独立错误代码。注意:在处理数组时由插件负责为其分配内存。 |
TransactionDef |
交易ID定义。此请求读取已完成,并由插件使用IIotDemand∷ReadDevice()启动。此时插件提供交易定义,并允许进行异步读取。注意:在处理数组时由插件负责为其分配内存。 |
备注
对于请求读取上的项目列表,值可由DAS引擎90以带外方式使用此方法向发出请求的插件报告。对于活动项目,OnReadComplete方法的工作方式与OnData方法相同。
OnWriteComplete
Declaration
HRESULT OnWriteComplete(
[in]DWORD dwCount,
[in,size_is(dwCoun)]PIHANDLE * phPlugInItems,
[in,size_is(dwCount)]HRESULT * pErrors,
[in]CTTRANSACTIONDEF TransactionDef
)
OnWriteComplete操作的参数定义:
DwCount |
传递的数组的大小。这是其写入已完成且正在报告事件的项目的数目。 |
phPlugInItems |
dwCount句柄的数组。这些句柄由插件提供,并标识其VTQ被报告的项目。注意:在处理数组时由插件负责为其分配内存。 |
pErrors |
HRESULT的数组。这是每个被报告的项目的独立错误代码。注意:在处理数组时由插件负责为其分配内存。 |
TransactionDef |
交易定义。此请求写入已完成,并由插件使用IIotDemand∷WriteDevice()启动。此时插件提供交易定义,并允许进行异步写入。注意:在处理数组时由插件负责为其分配内存。 |
备注
对于DAS引擎90写入的项目列表,使用此方法向特定数据交换协议插件报告写入完成事件。对于命令读取项目,OnWriteComplete方法的工作方式与OnReadComplete方法相同,只不过写入的数据不需要VTQ。
继续参考图8,IioPlugIn接口502是每个到DAS引擎层90的插件所给出的主要接口。IioPlugIn接口502有助于DAS引擎层90对插件进行一般操作。以下概括了IioPlugIn接口502的示例性实现的内容。
Declaration
[
object,
uuid(7AA3977A-AC55-llD2-8203-00A024A866AC),
helpstring(″IIoPlugIn Interface″),
pointer_default(unique)
]
interface IIoPlugIn:IUnknown
{
HRESULT Init(
[in]IIotDbServer* pIotDbServer,
[out]DWORD* nNumInterfaces
);
HRESULT Get IEnumGUID(
[in] REFIID riid,
[out,iid_is(riid)]LPUNKNOWN* ppUnk
);
HRESULT Shutdown();
HRESULT IsShutdownPossible([out]BOOL*bShutdown);
}
以下是实现IioPlugin接口502的示例性操作的说明。
Operations
GetIEnumGUID
Declaration
HRESULT GetIEnumGUID(
[in] REFIID riid,
[out,iid_is(riid)] LPUNKNOWN * ppUnk
)
GetEnumGuiD操作的参数说明:
Riid |
此方法返回枚举器,它枚举了此PlugIn.IEnumGUID所支持的顶层接口。 |
InitDeclarationHRESULT Init(
[in]IIotDbServer* pIotDbServer,
[out]DWORD* nNumInterfaces
)
Init操作的参数说明:
pIotDbServer |
DAS引擎中的一个对象给出的为插件所用的接口。 |
备注
通过init操作DAS引擎90可以初始化此插件,并将一个接口指针提供回到DAS引擎90中,被插件所用。
IsShutdownPossible
Declaration
HRESULT IsShutdownPossible([out]BOOL *bShutdown)
备注
通过IsShutdownPossible,DAS引擎90可询问各插件该插件是否能被关闭。通常插件会回答:
-TRUE当没有外部客户附加到插件上时以及回答
-FALSE当有外部客户附加到插件上时
返回代码:
S_OK-成功
S_FAIL-失败,表示插件可能处于未定义状态
Shutdown
Declaration
HRESULT Shutdown()
备注
通过Shutdown操作DAS引擎90可以通知特定插件数据访问服务器50将被关闭。响应此通知插件可能:
1.释放所有到DAS引擎的接口引用
2.通知客户(如果存在)DA服务器在断开连接中(以与IOPCShutdown∷ShutdownRequest(…)相同的方式)
注意shutdown不判定插件是否能被关闭。插件被通知可能的关闭,并以某种方法写入,以使得服务器可在调用Shutdonw()方法后的任何时刻被关闭。
返回代码:
S_OK-成功
S_FALSE-部分成功,表示插件可能处于未定义状态
现转到图9,标识了DAS引擎层90中执行的操作所支持的接口集。DAS引擎层90响应特定数据交换协议插件的调用执行这些接口,以帮助数据访问服务器50与以可通信方式连接的可能根据数据访问服务器的客户协议插件集所支持的多种数据交换协议操作的客户应用程序之间的数据通信。从而,下文说明的接口代表DAS引擎90所执行的用于与所有可安装DAS50上的实现本发明的所支持的数据交换协议插件交互的接口操作的父集。
通过IiotDbServer接口600数据交换协议插件可操纵DAS引擎90处理的群组,并调用特定的通用服务,如设置本地标识符,验证数据项等。
Declaration
[
object,
uuid(AD50D6D1-BAA1-11D2-A9BF-00A0C9ED0BF0),
helpstring(″IIotDbServer Interface″),
pointer_default(unique)
]
interface IIotDbServer:IUnknown
{
HRESULT GetModuleName(
[out,string]LPWSTR* ppModuleName
);
<!-- SIPO <DP n="27"> -->
<dp n="d27"/>
HRESULT AddGroup(
[in,string] LPCWSTR szName,
[in] BOOL bActive,
[in] DWORD dwRequestedUpdateRate,
[in] PIHANDLE hPlugInGroup,
[unique,in] LONG *pTimeBias,
[in] FLOAT *pPercentDeadband,
[in] DWORD dwLCID,
[out] CTHANDLE *phServerGroup,
[out] DWORD *pRevisedUpdateRate,
[in] IIopiData* pIIopiData,
[in] REFIID riid,
[out,iid_is(riid)] LPUNKNOWN *ppUnk
);
HRESULT GetStatus(
[out] CTSERVERSTATUS ** ppServerStatus
);
HRESULT RemoveGroup(
[in]CTHANDLE hServerGroup,
[in]BOOL bForce
);
HRESULT GetErrorString(
[in] HRESULT dwError,
[in] LCID dwLocale,
[out,string] LPWSTR* ppString
);
HRESULT QueryAvailableLocaleIDs(
[out] DWORD *pdwCount,
[out,size_is(,*pdwCount)]LCID **pdwLcid
);
HRESULT ValidateItems(
[in] DWORD dwNumItems,
[in,size_is(dwNumItems)] CTITEMDEF * pItemArray,
[out,size_is(,dwNumItems)] CTITEMRESULT **ppValidationResults,
[out,size_is(,dwNumItems)] HRESULT **ppErrors
);
HRESULT QueryOrganization(
[out]CTNAMESPACETYPE * pNameSpaceType
);
<!-- SIPO <DP n="28"> -->
<dp n="d28"/>
HRESULT BrowseCfgNode(
[in] CSHANDLE hCfgNode,
[out] CSHANDLE * phParent,
[in] BOOL bBranches,
[out] DWORD *pdwBranchCount,
[out,size_is(,*pdwBranchCount)]CSHANDLE **pphBranches,
[in] BOOL bLeafs,
[out] DWORD *pdwLeafCount,
[out,Size_is(,*pdwLeafCount)]CSHANDLE **pphLeaves,
[in] BOOL bTopics,
[out] DWORD *pdwTopicCount,
[out,size_is(,*pdwTopicCount)]CSHANDLE **pphTopics
);
HRESULT GetCfgNodeByNameId(
[in,string] LPCWSTR szName,
[out] CSHANDLE *hNode
);
HRESULT GetCfgNodeByPartialName(
[in] CSHANDLE hCurrentNode,
[in,string] LPCWSTR szName,
[out] CSHANDLE *hNode
);
HRESULT GetCfgNodeByTopicName(
[in,string] LPCWSTR szTopicName,
[out] CSHANDLE * bNode
);
HRESULT GetCfgNameIdByNode(
[in] CSHANDLE hNode,
[out,string] LPWSTR *ppName
);
<!-- SIPO <DP n="29"> -->
<dp n="d29"/>
HRESULT GetCfgNodeAttributes(
[in] DWORD dwNumCfgNodes,
[in,size_is(dwNumCfgNodes)] const CSHANDLE *pCfgNodeArray,
[out,size_is(,dwNumCfgNodes)]CTCFGNODEATTRIBUTES **
ppCtCfgNodeAttributes
);
}
以下是对IioDbServer接口600的范围内提供的示例性操作的说明。
Operations
AddGroup
Declaration
HRESULT AddGroup(
[in,string] LPCWSTR szName,
[in] BOOL bActive,
[in] DWORD dwRequestedUpdateRate,
[in] PIHANDLE hplugInGroup,
[unique,in] LONG * pTimeBias,
[in] FLOAT * pPercentDeadband,
[in] DWORD dwLCID,
[out] CTHANDLE * phServerGroup,
[out] DWORD * pRevisedUpdateRate,
[in] IIoPiData* pIIoPiData,
[in] REFIID riid,
[out,riid_is(riid)]LPUNKNOWN* ppUnk
)
参数
SzName |
被请求的群组的名称 |
Bactive |
如果新群组最初创建时应为活动,则此参数为TRUE |
dwRequestedUpdateRate |
建议更新率。此数字通常来自终端客户,并通过插件向下传递。此数字可能或不可能。 |
HplugInGroup |
此句柄将群组标识到插件。在后面的通知中必须记住它。 |
PtimeBias |
指向以分钟为单位的时间偏置的指针(像W32时区中的偏置域一样) |
PpercentBeadband |
滞后不工作区,防止报告抖动 |
DwLCID |
位置标识符 |
PhServerGroup |
此句柄将群组标识到DAS引擎。将其向后传递以便插件能在后面的交易中标识此群组。 |
PRevisedUpdateRate |
可能遇到的实际更新率。这可能与被请求的更新率一致,也可能不一致。 |
PIIoPiData |
插件传递其IoPiData接口。 |
Riid |
插件指定所需的接口类型。 |
PpUnk |
DAS引擎返回一个到所需接口类型的实例的指针,如果不存在则返回NULL。 |
备注
通过此操作数据交换协议插件可请求DAS引擎90创建群组。此操作可要求DAS引擎90从DAS50的设备协议层96处的特定服务器代码获取详细信息。
BrowseCfgNode
Declaration
HRESULT BrowseCfgNode(
[in] CSHANDLE hCfgNode,
[out] CSHANDLE * phParent,
[in] BOOL bBranches,
<!-- SIPO <DP n="31"> -->
<dp n="d31"/>
[out] DWORD *pdwBranchCount,
[out,size_is(,*pdwBranchCount)]CSHANDLE **pphBranches,
[in] BOOL bLeafs,
[out] DWORD *pdwLeafCount,
[out,size_is(,*pdwLeafCount)]CSHANDLE **pphLeaves,
[in] BOOL bTopics,
[out] DWORD *pdwTopicCount,
[out,size_is(,*pdwTopicCount)]CSHANDLE ** pphTopics
)
参数
HcfgNode |
所浏览的节点的安全句柄,对于ROOT为INVALID_CSHANDLE |
PhParent |
当前节点的安全句柄,如果该节点无父节点则为INVALID_CSHANDLE |
Bbranches |
是否用分支获取数组的标志 |
PdwBranchCount |
节点处的子分支的数目 |
PphBranches |
指向pdwBranchCount CSHANDLES数组的指针。DAS引擎创建此数组,并将指针向外传递给它作为返回值。注意:在处理数组时由插件负责为其分配内存。 |
Bleaves |
是否用叶获取数组的标志 |
PdwLeafCount |
节点处的子叶数目 |
PphLeaves |
指向pdwLeafCount CSHANDLES数组的指针。DAS引擎创建此数组,并将指针传递给它(向外)作为返回值。注意:在处理数组时由插件负责为其分配内存。 |
Btopics |
是否用标题获取数组的标志 |
PdwTopicCount |
节点处的访问路径/标题数目 |
PphTopics |
指向pdwTopicCount CSHANDLES数组的指针。DAS引擎创建此数组,并将指针传递给它(向外)作为返回值。注意:在处理数组时由插件负责为其分配内存。 |
备注
通过此操作客户应用程序可以通过一个特定的数据交换协议插件请求DAS引擎90浏览指定节点并取出所有子对象:子分支、叶和访问路径/标题。GetCfgNameIdByNodeDeclarationHRESULT GetCfgNameIdByNode(
[in] CSHANDLE hNode,
[out,string] LPWSTR *ppName
)参数
HNode |
节点DAS引擎句柄 |
ppName |
完全合格的节点名称的名称。 |
备注
通过GetCfgNameIdByNode操作插件可以取出节点的完全合格名称标识符(包括直到节点的分隔符的完整名称路径)
GetCfgNodeAttributes
Declaration
HRESULT GetCfgNodeAttributes(
[in]
DWORD dwNumCfgNodes,
[in,size_is(dwNumCfgNodes)] const CSHANDLE * PCfgNodeArray,
[out,size_is(,dwNumCfgNodes)]CTCFGNODEATTRIBUTES **
ppCtCfgNodeAttributes
)
参数
DwNumCfgNodes |
获取属性的节点数目。 |
PcfgNodeArray |
获取属性的节点的安全句柄数组: |
ppCtCfgNodeAttributes |
指向dwNumCfgNodes cfg节点属性的数组的指针。DAS引擎创建此数组,并将指针向外传递给它作为返回值。注意:在处理数组时由插件负责为其分配内存。 |
备注
通过此操作客户应用程序可以通过一个特定的数据交换协议插件请求DAS引擎90浏览指定节点并取出所有子对象:子分支、叶和访问路径/标题。
GetCfgNodeByNameId
Declaration
HRESULT GetCfgNodeByNameId(
[in,string] LPCWSTR szName,
[out] CSHANDLE * hNode
)
参数
szName |
完全合格的节点名称的名称。 |
HNode |
节点DAS引擎句柄 |
备注
通过此操作插件可以请求DAS引擎90提供一个相应于一个由插件指定的完全合格的名称标识符(包括直到节点的分隔符的完整名称路径)的节点句柄。
GetCfgNodeByPartialName
Declaration
HRESUT GetCfgNodeByPartialName(
[in] CSHANDLE hCurrentNode,
[in,string] LPCWSTR szName,
[out] CSEANDLE * hNode
)
参数
hCurrentNode |
开始搜索的节点的DAS引擎句柄,如果从根开始搜索则为INVALID_CSHANDLE。 |
SzName |
紧接hCurrentNode表示的节点下方开始的名称的某些片段。例如,如果一个完全合格的项目名称为“Server.Portl.PLC1.Item1”,则如果hCurrentNode表示“Server”根下方的“Port1.”节点(“Server.Port1”,则可以使用hCurrentNode和“PLC1”取出“Server.Port1.PLC1.”的句柄。同样的,可使用hCurrentNode和“PLC1.Iteml”取出叶的句柄。 |
HNode |
节点DAS引擎句柄。 |
备注
通过此操作插件可以请求DAS引擎90提供一个对应于由当前节点和开始于当前节点的名称片段所完全指定的名称标识符的节点句柄。
GetCfgNodeByropicName
Declaration
HRESULT GetCfgNodeByTopicName(
[in,string] LPCWSTR szTopicName,
[out] CSHANDLE * hNode
)
参数
szTopicName |
完全合格的标题点称的名称。 |
HNode |
节点DAS引擎句柄 |
备注
通过此操作插件可以请求DAS引擎90通过指定一个完全合格的标题/OPC访问路径的名称标识符来提供一个节点句柄。
GetErrorString
Declaration
HRESULT GetErrorString(
[in] HRESULT dwError,
[in] LCID dwLocale,
[out,string] LPWSTR * ppString
)
参数
dwError |
错误代码 |
dwLocale |
位置标识符 |
ppString |
返回的错误文本 |
备注
通过此操作插件可以请求DAS引擎90为指定的错误代码和位置提供错误文本。
GetModuleName
Declaration
HRESULT GetModuleName(
[out,string]LPWSTR* ppModuleName
)
参数
ppModuleName |
服务器EXE模块名称,去掉扩展名。 |
备注
通过此操作插件可以请求DAS引擎90返回DAS 50的EXE模块名称,去掉任何文件扩展名。
GetStatus
DeclarationHRESULT GetStatus(
[out] CTSERVERSTATUS ** ppServerStatus
)
参数
ppServerStatus |
DAS引擎保存一个本地CTSERVERSTATUS结构体,并返回一个指向它的指针。 |
备注
通过此操作插件可以请求DAS引擎90提供一个指向DAS 50总体状态的指针。
QueryAvailableLocaleIDs
Declaration
HRESULT QueryAvailableLocaleIDs(
[out]DWORD *pdwCoun,
[out,size_is(,*pdwCount)] LCID **pdwLcid
)
参数
pdwCount |
位置标识符的数目 |
pdwLcid |
位置标识符列表 |
备注
通过此操作插件可以请求DAS引擎90提供所支持的位置标识符的列表。
QueryOrganization
Declaration
HRESULT QueryOrganization(
[out] CTNAMESPACETYPE * pNameSpaceType
)
参数
PnameSpaceType |
DAS引擎返回CT_NS_HIERARCHIAL或CT_NS_FLAT其中之一 |
备注
通过此操作插件可以查询服务器的配置组织。服务器的配置为平级的或分等级的。
RemoveGroup
Declaration
HRESULT RemoveGroup(
[in] CTHANDLE hServerGroup,
[in] BOOL bForce
)
参数
hServerGroup |
此句柄将群组指定到DAS引擎。它必须是通过先前对AddGroup方法的调用的phServerGroup变量返回的句柄。 |
备注
通过此操作插件可以请求DAS引擎90删除先前创建的群组。
ValidateItems
Declaration
HRESULT ValidateItems(
[in] DWORD dwNumItems,
[in,size_is(dwNumItems)] CTITEMDEF * pItemArray,
[out,size_is(,dwNumItems)] CTITEMRESULT ** ppValidationResults,
[out,size_is(,dwNumItems)] HRESULT ** ppErrors
)
参数
dwNumItems |
验证项目的数目。 |
PItemArray |
dwNumItems CTITEMDEF结构体的数组。数组中的每个元素定义一个将被创建或定位,或添加到群组中的项目。 |
ppValidationResults |
指向dwNumItems CTITEMRESULT结构体的数组的指针。DAS引擎创建此数组,并将指针向外传递给它作为返回值。注意:在处理数组时由插件负责为其分配内存。 |
PpErrors |
HRESULT的数组。这是每个被报告的项目的独立错误代码。DAS引擎创建此数组,并将指针向外传递给它作为返回值。注意:在处理数组时由插件负责为其分配内存。 |
备注
此操作与群组对象的IIotItemMgt接口606中的AddItems操作(在下文中说明)相同。由于项目语法独立于群组,此操作在项目定义上执行相同的验证。通过此操作插件可以满足无群组的客户活动(仅对于请求的调用)。
通过IiotDemand接口602插件可以在创建、添加和激活了群组和物理数据项后为指定数据项的数组向DAS引擎90提交带外请求(在常规更新时段外)
Declaration
[
object,
uuid(AD50D6D5-B4A1-11D2-A9BF-00A0C9ED0BF0),
helpstring(″IIotDemand Interface″),
pointer_default(unique)
]
<!-- SIPO <DP n="39"> -->
<dp n="d39"/>
interface IIotDemand:IUnknown
{
HRESULT ReadCache(
[in] DWORD dwNumItems,
[in,size_is(dwNumItems)] CTHANDLE * phCoreToolkit,
[out,size_is(,dwNumItems)] CTITEMSTATE ** ppItemValues,
[out,size_is(,dwNumItems)] HRESULT ** ppErrors
);
HRESULT ReadDevice(
[in] DWORD dwCount,
[in,size_is(dwCount)] CTHANDLE * phCoreToolkit,
[in] CTTRANSACTIONDEF TransactionDef,
[unique,in] LONG * pTimeBias,
[in] DWORD dwLCID,
[out,size_is(,dwCount)] HRESULT ** ppErrors,
[out] CTHANDLE* CancelID
);
HRESULT WriteDevice(
[in] DWORD dwCount,
[in,size_is(dwCount) ] CTHANDLE * phCoreToolkit,
[in,size_is(dwCount) ] VARIANT * pItemValues,
[in] CTTRANSACTIONDEF TransactionDef,
[unique,in] LONG * pTimeBias,
[in] DWORD dwLCID,
[out,size_is(,dwCount)] HRESULT ** ppErrors,
[out] CTHANDLE* CancelID
);
HRESULT Cancel(
[in] CTHANDLE CancelID
);
}
说明
在创建、添加和激活群组和项目后,通过此接口插件可以向DAS引擎90保存/监控的指定项目数组提交带外数据访问请求。在很多情况下,这些操作将花费很长时间,并将异步进行。这些异步调用的完成将在IIoPiData接口的方法上报告。
以下是对于实现IiotDemand接口602的示例性操作的说明。
Operations
Cancel
Declaration
HRESULT Cancel(
[in] CTHANDLE CancelID
)
备注
通过此操作插件可以取消任何DAS引擎90先前请求的待处理的异步交易(请求调用或刷新)。
ReadCsche
Declaration
HRESULT ReadCache(
[in] DWORD dwNumItems,
[in,size_is(dwNumItems)] CTHANDLE * phCoreToolkit,
[out,size_is(,dwNumItems)] CTITEMSTATE ** ppItemValues,
[out,size_is(,dwNumItems)] HRESULT ** ppErrors
)
参数
DwNumItems |
将从高速缓冲存储器中读取的项目的计数。 |
PhCoreToolkit |
dwNtmItems句柄的数组。这是将项目标识到DAS引擎的句柄,并且在IIotItemMgt∷AddItems期间被提供给插件。此数组由插件提供。 |
PpItemValues |
指向CTITEMSTATE结构体数组的指针。此数组由DAS引擎创建,指向它的指针被向外传递作为返回值。数组中的每个CTITEMSTATE表示指定项目的当前项目状态。注意:在处理数组时由插件负责为其分配内存。 |
PpErrors |
指向HRESULTs数组的指针。此数组由DAS引擎创建,指向它的指针被向外传递作为返回值。每个HRESULT为指定项目给出一个错误代码。注意:在处理数组时由插件负责为其分配内存。 |
备注
此操作同步进行,并调用DAS引擎90从包含dwNumItems项目的数组的高速缓冲存储器返回当前VTQ。
ReadDevice
Declaration
HRESULT ReadDevice(
[in] DWORD dwCount,
[in,size_is(dwCount)] CTHANDLE * phCoreToolkit,
[in] CTTRANSACTIONDEF TransactionDef,
[unique,in] LONG * pTimeBias,
[in] DWORD dwLCID,
[out,size_is(,dwCount)] HRESULT ** ppErrors,
[out] CTHANDLE* CancelID
)
参数
DwCount |
被请求项目的计数。 |
PhCoreToolkit |
dwCount句柄的数组。这是将项目标识到DAS引擎的句柄,并且在IIotItemMgt∷AddItems期间被提供给插件。此数组由插件提供。 |
TransactionDef |
交易定义。此操作将在使用IIoPiData∷On WriteComplete()通知完成时唯一标识请求读取交易。此标识符由DAS引擎提供。 |
PTimeBias |
指向以分钟为单位的时间偏置的指针(像W32时区中的偏置域一样) |
DwLCID |
位置标识符,OPC只会对相同群组的项目进行请求调用,因此OPC插件将提供群组的位置标识符和时间偏置。 |
PpErrors |
指向HRESULT数组的指针。有可能一个或多个指定项目不存在,或者无效。此数组由DAS引擎创建,指向它的指针被向外传递作为返回值。注意:在处理数组时由插件负责为其分配内存。 |
CancelID |
插件取消交易的取消标识符 |
备注
此操作异步进行。DAS引擎90在IIoPiData∷OnReadComplete()上通知完成。通过此操作插件可以请求DAS引擎90执行项目列表的请求读取。一旦任何总线活动完成即开始此请求读取,并且以高于任何扫描的数据的优先权返回。
WriteDevice
Declaration
HRESULT WriteDevice(
[in] DwORD dwCount,
[in,size_is(dwCount)] CTHANDLE * phCoreToolkit,
[in,size_is(dwCount)] VARIANT * pItemValues,
[in] CTTRANSACTIONDEF TransactionDef,
[unique,in] LONG * pTimeBias,
[in] DWORD dwLCID,
[out,size_is(,dwCount)] HRESULT ** ppErrors,
[out] CTHANDLE* CancelID
)
参数
DwCount |
要写入的项目的计数。 |
PhCoreToolkit |
dwCount句柄的数组。这是将项目标识到DAS引擎的句柄,并且在IIotItemMgt∷AddItems期间被提供给插件。此数组由插件提供。 |
PItemValues |
dwCount变量值的数组。它们是项目新值。 |
TransactionDef |
交易定义。此操作将在使用IIoPiData∷On WriteComplete()通知完成时唯一标识请求读取交易。此标识符由DAS引擎提供。 |
PTimeBias |
指向以分钟为单位的时间偏置的指针(像W32时区中的偏置域一样) |
DwLCID |
位置标识符,OPC只会对相同群组的项目进行请求调用,因此OPC插件将提供群组的位置标识符和时间偏置。 |
PpErrors |
指向HRESULT数组的指针。有可能一个或多个指定项目不存在,或者无效。此数组由DAS引擎创建,指向它的指针被向外传递作为返回值。注意:在处理数组时由插件负责为其分配内存。 |
CancelID |
插件取消交易的取消标识符 |
备注
此操作异步进行。DAS引擎90在IIoPiData∷OnReadComplete()上通知完成。通过此操作插件可以请求DAS引擎90执行项目列表写入。一旦任何总线活动完成即开始此写入,并且以高于任何扫描的数据的优先权返回。
通过IiotGroupStateMgt接口604插件可操纵在DAS 50上创建的群组。
Declaration
[
object,
uuid(2030A921-0788-11d3-82C2-00A024A866AC),
helpstring(″IIotGroupStateMgt Interface″),
pointer_default(unique)
]
interface IIotGroupStateMgt:IUnknown
{
HRESULT GetState(
[out] DWORD * pUpdateRate,
[out] BOOL * pActive,
[out,string] LPWSTR * ppName,
[out] LONG * pTimeBias,
[out] FLOAT * pPercentDeadband,
[out] DWORD * pLCID,
[out] PIHANDLE * phPlugInGroup,
[out] CTHANDLE * phCoreToolkitGroup
);
HRESULT SetState(
[unique,in] DWORD * pRequestedUpdateRate,
[out] DWORD * pRevisedUpdateRate,
[unique,in] BOOL * pActive,
[unique,in] LONG * pTimeBias,
[unique,in] FLOAT * pPercentDeadband,
[unique,in] DWORD * pLCID,
[unique,in] PIHANDLE * phClientGroup
);
HRESULT SetName (
[in,string] LPCWSTR szName
);
HRESULT CloneGroup(
[in,string] LPCWSTR szName,
[in] IIoPiData* pIIoPiData,
[out] CTHANDLE *phServerHandle,
[in] REFIID riid,
[out,iid_is(riid)] LPUNKNOWN * ppUnk
);
}
说明
通过此接口插件可操纵在DAS 50上创建的群组。
以下是对于实现IiotGroupStateMgt接口604的示例性操作的说明。
Operations
CloneGroup
Declaration
HRESULT CloneGroup(
[in,string] LPCWSTR szName,
[in] IIoPiData* pIIoPiData,
[out] CTHANDLE *phServerHandle,
[in] REFIID riid,
[out,iid_is(riid)] LPUNKNOWN *ppUnk
)
参数
SzName |
新群组的唯一名称。 |
PIIoPiData |
插件传递其IoPiData接口。 |
Riid |
插件指定所需的接口类型。 |
PpUnk |
DAS引擎返回指向所需接口类型的实例的指针,如果不存在则返回NULL。 |
备注
此操作创建现有群组的复本,与原群组具有相同特征。
GetState
Declaration
HRESULT GetState(
[out] DWORD * pUpdateRate,
[out] BOOL * pActive,
[out,string] LPWSTR * ppName,
[out] LONG * pTimeBias,
[out] FLOAT * pPercentDeadband,
[out] DWORD * pLCID,
[out] PIHANDLE * phPlugInGroup,
[out] CTHSANDLE * phCoreToolkitGroup
)
参数
参数 |
说明 |
PUpdataRate |
当前更新率。更新率以毫秒为单位。 |
Pactive |
群组的当前活动状态。 |
PpName |
群组的当前名称 |
PTimeBias |
群组的时区偏置(以分钟为单位) |
PPercentDeadband |
将引起向客户对某项目值进行异常报告时,该值的变化百分比。此参数仅适用于具有模拟dwEuType的群组上的项目。[参见一般属性部分对不工作区百分比的讨论] |
PLCID |
群组的当前LCID |
phPlugInGroup |
客户(插件)提供的群组句柄 |
phCoreToolkitGroup |
服务器生成的群组句柄 |
备注:此操作获取群组的当前状态。
SetName
Declaration
HRESULT SetName(
[in,string] LPCWSTR szName
)
备注:
此操作更改现有群组的名称。名称必须是唯一的。
SetState
Declaration
HRESULT SetState(
[unique,in] DWORD * pRequestedUpdateRate,
[out] DWORD * pRevisedUpdateRate,
[unique,in] BOOL * pActive,
[unique,in] LONG * pTimeBias,
[unique,in] FLOAT * pPercentDeadband,
[unique,in] DWORD * pLCID,
[unique,in] PIHANDLE * phClientGroup
)
参数
参数 |
说明 |
pRequestedUpdateRate |
客户请求的群组的新的更新率(以毫秒为单位) |
pRevisedUpdateRate |
服务器能为此群组提供的最接近更新率。 |
Pactive |
TRUE(非零)激活群组。FALSE(0)取消激活群组。 |
PtimeBias |
群组的时区偏置(分钟)。 |
pPercentDeadband |
将引起向客户对某项目值进行异常报告时,该值的变化百分比。此参数仅适用于具有模拟dwEuType的群组上的项目。参见一般属性部分对不工作区百分比的讨论。 |
PLCID |
群组要使用的位置标识符 |
PhClientGroup |
客户提供的新的群组句柄。此句柄在由群组IDataObject提供给客户的IAdvise的数据流中返回。 |
备注
通过此操作客户可设置群组的多种属性。使用指向“in”项目的指针以便客户可通过传递NULL指针忽略客户不希望更改的属性。pRevisedUpdateRate变量必须包含有效指针。
通过一个IiotItemMgt接口606插件可以请求DAS引擎90在群组中添加、验证和删除项目。IiotItemMgt接口606由一个群组对象在DAS引擎90中实现。
Declaration
[
object,
uuid(AD50D6D3-B4A1-11D2-A9BF-00A0C9ED0BF0),
helpstring(″IIotItemMgt Interface″),
pointer_default(unique)
]
interface IIotItemMgt:IUnknown
{
HRESULT AddItems(
[in] DWORD dwNumItems,
[in,size_is(dwNumItems)] CTITEMDEF * pItemArray,
[out,size_is(,dwNumItems)] CTITEMRESULT ** ppAddResults,
[out,size_is(,dwNumItems)] HRESULT ** ppErrors
);
HRESULT ValidateItems(
[in] DWORD dwNumItems,
[in,ize_is(dwNumItems)] CTITEMDEF * pItemArray,
[out,size_is(,dwNumItems)) CTITEMRESULT ** ppValidationResults,
[out,size_is(,dwNumItems)] HRESULT ** ppErrors
);
HRESULT RemoveItems (
[in] DWORD dwNumItems,
[in,size_is(dwNumItems)] CTHANDLE * phCoreToolkit,
[out,size_is(,dwNumItems)] HRESULT ** ppErrors
);
HRESULT SetActiveState (
[in] DWORD dwNumItems,
[in,size_is(dwNumItems)] CTHANDLE * phCoreToolkit,
[in] BOOL bActive,
[out,size_is(,dwNumItems)] HRESULT ** ppErrors
);
<!-- SIPO <DP n="49"> -->
<dp n="d49"/>
HRESULT SetClientHandles(
[in] DWORD dwNumItems,
[in,size_is(dwNumItems)] CTHANDLE * phCoreToolkit,
[in,size_is(dwNumItems)] PIHANDLE * phPlugIn,
[out,size_is(,dwNumItems)] HRESULT ** ppErrors
);
HRESULT SetDatatypes(
[in] DWORD dwCount,
[in,size_is(dwCount)] CTHANDLE * phCoreToolkit,
[in,size_is(dwCount)] VARTYPE * pRsquestedDatatypes,
[out,size_is(,dwCount)] HRESULT ** ppErrors
);
HRESULT CreateEnumerator(
[in] REFIID riid,
[out,iid_is(riid)] LPUNKNOWN* ppUnk
);
HRESULT GetItemCount(
[out] DWORD* dwItemCount
);
HRESULT Refresh(
[in] CTDATASOURCE dwSource,
[in] CTTRANSACTIONDEF TransactionDef,
[out] DWORD *pdwCancelID
);
}
说明
IiotItemMgt接口606由一个群组对象在DAS引擎90中实现。通过此操作可以在群组中添加、验证和删除项目。以下是实现IiotItemMgt接口606的示例性操作的说明。
Openations
AddItems
Declaration
HRESULT AddItems(
[in] DWORD dwNumItems,
[in,size_is(dwNumItems)] CTITEMDEF * pItemArray,
[out,size_is(,dwNumItems)] CTITEMRESULT ** ppAddResults,
[out,size_is(,dwNumItems)] HRESULT ** ppErrors
)
参数
DwNumItems |
要添加到此群组的项目数目。 |
PItemArray |
dwNumItems CTITEMDEF结构体数组。数组中的每个元素定义一个要创建或定位,以及添加到群组中的项目。 |
PpAddResults |
指向dwNumItems CTITEMRESULT结构数组的指针。DAS创建此数组,并将指向它的指针向外传递作为返回值。注意:在处理数组时由插件负责为其分配内存。 |
PpErrors |
HRESULT数组。这是每个被报告的项目的独立错误代码。DAS创建此数组,并将指向它的指针向外传递作为返回值。注意:在处理数组时由插件负责为其分配内存。 |
备注
此操作提供与OPC相同的列表接口功能。通过此操作插件可以请求DAS引擎90创建项目列表(或提供其地址,如果存在)并返回整个列表的结果代码。
CreateEnumerator
Declaration
HRESULT CreataEnumeratot(
[in]REFIID riid,
[out,iid_is(riid)] LPUNKNOWN* ppUnk
)
参数
Riid |
被请求的接口标识符。 |
PpUnk |
返回的被请求的接口指针或NULL。 |
备注
通过此操作插件可以请求DAS引擎90在DAS引擎90群组中创建项目的枚举器。
GetItemCount
Declaration
HRESULT GetItemCount(
[out]DWORD* dwItemCount
)
备注
通过此操作插件可以请求DAS引擎90提供群组中的项目的总数,不论其状态如何。
Rafresh
Declaration
HRESULT Refresh(
[in] CTDATASOURCE dwSource,
[in] CTTRANSACTIONDEF TransactionDef,
[out] DWORD *pdwCancelID
)
参数
DwSource |
被请求的数据源:高速缓冲存储器或设备。 |
TransactionDef |
交易定义。此操作将在使用IIoPiData∷OnData()通知完成时唯一标识更新交易。此标识符由DAS引擎提供。 |
PdwCancelID |
DAS引擎提供的取消标识符 |
备注
通过操作插件可以请求DAS引擎90强制更新群组中的活动项目。
RemoveItems
Declaration
HRESULT RemoveItems(
[in] DWORD dwNumItems,
[in,size_is(dwNumItems)] CTHANDLE * phCoreToolkit,
[out,size_is(,dwNumItems)] HRESULT ** ppErrors
)
参数
DwNumItems |
要从此群组删除的项目数目。特殊情况:值DWORD_MAX表示删除当前在群组中的所有项目。 |
PhCoreToolkit |
dwNumItems句柄的数组。这些句柄将每个项目标识到DAS引擎。句柄在调用AddItems()方法时由DAS引擎创建,并作为ppAddResults数组中的CTITEMRESULT结构体的一部分向外传递。 |
PpErrors |
dwNumItems HRESULT数组。这是每个被报告的项目的独立的错误代码。DAS引擎创建此数组,并将指向它的指针作为返回值向外传递。注意:在处理数组时由插件负责为其分配内存。 |
备注
通过此操作插件可以请求DAS引擎90删除先前添加到群组的项目列表。
SetActiveState
Declaration
HRESULT SetActiveState(
[in] DWORD dwNumItems,
[in,size_is(dwNumItems)] CTHANDLE * phCoreToolkit,
[in] BOOL bActive,
[out,size_is(,dwNumItems)] HRESULT ** ppErrors
)
参数
DwNumItems |
要在此群组中激活的项目数目。 |
PhCoreToolkit |
dwNumItems句柄的数组。这些句柄将每个项目标识到DAS引擎。此句柄在调用AddItems()方法时由DAS引擎创建,并作为ppAddResults数组中的CTITEMRESULT结构体的一部分向外传递。 |
BActive |
dwNumItem激活/取消激活标志数组。 |
PpErrors |
dwNumItems HRESULT数组。这是每个被报告的项目的独立的错误代码。DAS引擎创建此数组,并将指向它的指针作为返回值向外传递。注意:在处理数组时由插件负责为其分配内存。 |
备注
通过此操作插件可以请求DAS引擎90激活和取消激活先前添加到群组项目列表。被激活的项目可以使用IIoPiData∷OnReadComplete()更新其VTQ。SetClientHandlesDeclarationHRESULT SetClientHandles(
[in]DWORD dwNumItems,
[in,size_is(dwNumItems)] CTHANDLE * phCoreToolkit,
[in,size_is(dwNumItems)] PIHANDLE * phPlugIn,
[out,size_is(,dwNumItems)] HRESULT ** ppErrors
)
参数
DwNumItems |
要更改客户句柄的项目的数目。 |
PhCoreToolkit |
dwNumItems句柄的数组。这些句柄将每个项目标识到DAS引擎。此句柄在调用AddItems()方法时由DAS引擎创建,并作为ppAddResults数组中的CTITEMRESULT结构体的一部分向外传递。 |
PhPlugIn |
新的dwNumItem客户句柄数组。 |
PpErrors |
dwNumItems HRESULT数组。这是每个被报告的项目的独立的错误代码。DAS引擎创建此数组,并将指向它的指针作为返回值向外传递。注意:在处理数组时由插件负责为其分配内存。 |
备注
通过此操作插件可以请求DAS引擎90为现有项目设置新的客户句柄。
SetDatatypes
Declaration
HRESULT SetDatatypes(
[in]DWORD dwCount,
[in,size_is(dwCouut)] CTHANDLE * phCoreToolkit,
[in,size_is(dwCount)] VARTYPE * pRequestedDatatypes,
[out,size_is(,dwCount)] HRESULT ** ppErrors
)
参数
DwNumItems |
要设置其数据类型的项目的数目。 |
PhCoreToolkit |
dwNumItems句柄的数组。这些句柄将每个项目标识到DAS引擎。此句柄在调用AddItems()方法时由DAS引擎创建,并作为ppAddResults数组中的CTITEMRESULT结构体的一部分向外传递。 |
PRequestdDatatypes |
dwNumItems请求的新数据类型的数组。 |
PpErrors |
dwNumItems HRESULT数组。这是每个被报告的项目的独立的错误代码。DAS引擎创建此数组,并将指向它的指针作为返回值向外传递。注意:在处理数组时由插件负责为其分配内存。 |
备注
通过此操作插件可以请求DAS引擎90为现有项目设置新的数据类型。
ValidateItems
Declaration
HRESULT ValidateItems(
[in] DWORD dwNumItems,
[in,size_is(dwNumItems)] CTITEMDEF * pItemArray,
[out,size_is(,dwNumItems)] CTITEMRESULT ** ppValidationResults,
[out,size_is(,dwNumItems)] HRESULT ** ppErrors
)
参数
DwNumItems |
要为此群组验证的项目的数目。 |
PitemArray |
dwNumItems CTITEMDEF结构体数组。数组中的每个元素定义一个要被创建或定位,以及添加到群组中的项目。 |
PpValidationReSults |
指向dwNumItems CTITEMRESULT结构体数组的指针。DAS引擎创建此数组,并将指向它的指针作为返回值向外传递。注意:在处理数组时由插件负责为其分配内存。 |
PpErrors |
HRESULT数组。这是每个被报告的项目的独立的错误代码。DAS引擎创建此数组,并将指向它的指针作为返回值向外传递。注意:在处理数组时由插件负责为其分配内存。 |
备注
此操作与先前说明的AddItems相同。但是,实际上DAS引擎90没有创建项目。通过此操作插件可以确定项目名称是否有效,以及当项目名称有效时确定其类型和状态。
本发明的说明性实施方式及其某些变体已在附图和伴随的书面说明中提供。本发明不限于这些实施方式。本发明将在考虑到下文的权利要求书定义的此次发布和本发明所允许的最大范围内覆盖所发布的实施方式以及其他进入本发明的范围和精神的实施方式。