WINCE平台上开发OPC程序所遇到的问题和解决方案

来源:互联网 发布:数据库引擎是什么 编辑:程序博客网 时间:2024/06/05 06:20
        OPC(OLE for Process Control, 用于过程控制的OLE)是一个工业标准,管理这个标准国际组织是OPC基金会,OPC基金会现有会员已超过220家。遍布全球,包括世界上所有主要的自动化控制系统、仪器仪表及过程控制系统的公司。基于微软的OLE(现在的Active X)、COM (部件对象模型)和DCOM (分布式部件对象模型)技术。OPC包括一整套接口、属性和方法的标准集,用于过程控制和制造业自动化系统。
       
        OPC全称是Object Linking and Embedding(OLE) for Process Control,它的出现为基于Windows的应用程序和现场过程控制应用建立了桥梁。在过去,为了存取现场设备的数据信息,每一个应用软件开发商都需要编写专用的接口函数。由于现场设备的种类繁多,且产品的不断升级,往往给用户和软件开发商带来了巨大的工作负担。通常这样也不能满足工作的实际需要,系统集成商和开发商急切需要一种具有高效性、可靠性、开放性、可互操作性的即插即用的设备驱动程序。在这种情况下,OPC标准应运而生。OPC标准以微软公司的OLE技术为基础,它的制定是通过提供一套标准的OLE/COM接口完成的,在OPC技术中使用的是OLE 2技术,OLE标准允许多台微机之间交换文档、图形等对象。
        WINCE平台上开发OPC程序所遇到的问题
        一般用户比较熟悉Win32平台的OPC应用程序,除了Win32平台,OPC应用程序能够运行在WCE平台上呢?答案是肯定可以的。但目前只能支持进程内的OPC服务器,也就是要把OPC服务器开发成DLL的形式。
         开发成DLL有什么好处呢?为什么要这样做呢?具体原因是:如果是EXE形式,则客户端程序和服务器程序就运行在两个不同的进程,跨进程的访问一定要通过列集、散集才能调用另外一个进程的函数,OPC DA列集和散集需要用到这两个代理和存根DLL(opccomn_ps.dll和opcproxy.dll,这两个DLL可以从OPC基金会组织网站上下载或者分别使用Opccomn.idl和OPCDA.IDL文件产生,具体做法如果不知道而确实想知道,可以跟我联系) 。这两个DLL没办法移植到WCE平台中,所以这个是目前WINCE平台中不能把OPC服务器开发成EXE形式的直接原因。
要使OPC客户程序跳过这两个DLL直接能访问OPC服务器程序,只能把服务器开发成为DLL的形式,这样客户程序和服务程序就运行在同一个进程地址空间内。并且OPC服务器程序的线程模式(ThreadingModel)通过注册表设定为FreeThread或者Both,服务程序就能正确地被客户程序调用。
         WCE支持的API函数和Win32的API函数类似,但有些并没有支持,因此开发进程内服务器过程中还会遇到其它小问题,以下逐一介绍,并给出解决的方法。
1,进程内OPC服务器不支持DCOM
图3-3就是一台机器A上的OPC客户程序访问另外一台机器B上的OPC服务器的过程。要实现DCOM的功能,一定需要提供COM库中的服务控制管理器也就是SCM,在Win32中以RPCSS.dll或者RPCSS.EXE的形式提供给用户,在system32文件夹上可以找到该文件。目前WCE上不支持DCOM,但从长远来看,微软以后可能会在WCE平台上实现DCOM的功能。 另外,WINCE的注册表里并没有AppID这个子健.
2, 不能使用COM库的CoGetMalloc函数。
COM库函数CoGetMalloc可以让程序员非常方便地访问内存管理器,进行内存的分配和释放。但WCE并不支持这个API函数,所以用户可以使用CoTaskMemAlloc、CoTaskMemFree来替代CoGetMalloc。还有就是这几个COM库的API函数不需要进行COM库的初始化就可以使用。
3.  不支持组件分类的功能
在Win32平台上上的服务器程序可以组建分类作为注册表的一部分内容,这样允许客户程序更加方便地浏览OPC服务器,目前WCE并不提供该功能,然而这不不是OPC服务器关键的功能。客户程序可以通过枚举注册表里的“OPC”子键,获得注册到WCE操作系统里的OPC服务器ProgID,然后把服务器的ProgID用列表框显示出来。
4,不支持CLSIDFromPROGID函数
CLSIDFromPROID这个函数可以使客户端程序很方便地把服务器的ProgID转化成为CLSID。可以通过查询注册表的方式来获得CLSID。
5,不支持CoFileTimeNow函数
CoFileTimeNow这个函数用来获取系统的时间并把它放到FILETIME结构的函数里面。比如服务器启动时间属性就是通过这个函数获得的。WCE不支持该函数,但可以通过以下HRESULT My_CoFileTimeNow(FILETIME * lpFileTime)来等效CoFileTimeNow。
inline HRESULT My_CoFileTimeNow( FILETIME * lpFileTime )
{
SYSTEMTIME st;
GetSystemTime( &st );
return( SystemTimeToFileTime( &st, lpFileTime ) ? S_OK : E_FAIL);
}
#define CoFileTimeNow My_CoFileTimeNow
6 不支持CreateDataAdviseHolder函数
CreateDataAdviseHolder这个函数在实现IDataObject接口时非常有用。由于WCE不提供该函数,所以需要自己编写一个实现同样功能的函数。
更多请访问:http://www.lyctr.com/shownews.asp?id=195
原创粉丝点击