当前时间:
导航菜单
文章正文
OPC DA客户端的三种实现方式
作者:  发布于2014-05-18 22:04    文字:【】【】【
        设计时需要注意OPC对象的VARAINT结构类型、引用计数问题、内存管理问题和处理错误返回代码问题。由于一个OPC客户程序可能与多个OPC服务器相连,因此设计时也最好采用多线程,同时与多个OPC服务器程序进行交换以保证较高的通信效率。另外客户程序中OPC接口部分如何与其它功能模块进行数据交换需要根据实际情况仔细考虑。
2.1 使用MFC的COM库函数开发OPC客户端
    直接使用COM库函数开发OPC客户端,是最基本也是最灵活的方式,这种开发方式难度和工作量都大,要求开发人员对OPC规范和COM技术原理又比较深入的了解。早些时候VisualC++编译器还不支持模板,因此,它们不得不借助非模板的其它手段来将COM功能掺入类中。Microsoft通过加入一些虚函数到CCmdTarget类和一些宏中解决了这个问题,使得在MFC中实现COM接口有了可能。
    客户要创建一个COM对象首先应得到类厂对象,再由类厂对象创建COM对象。为了实现类厂对象,MFC提供了一个通用的类厂COleObjectFactory,其从CCmdTarget派生,并实现了IclassFactory2接口。在COleObjectFactory的成员中,最主要的是对象的类标识符(CLSID)和类型信息,类厂的CreateInstance成员函数利用这些信息在运行中创建COM对象。
    OPCServer应用程序包括了一个Server对象、多个Group对象、多个Item对象,Server对象实现IOPCServer接口;Group对象实现IOPCItemMgt、IOPCSyncIO接口;Item对象不实现任何接口,只是建立与数据源的连接。
    数据通信是通过OPC客户对OPC服务器的多次调用完成的。OPC客户首先要通过类厂对象创建OPCServer对象,由OPCGroup对象的IUnknown接口查询到IOPCServer接口,再通过调用这一接口根据客户需要增加多个OPCGroup对象;这样OPC客户就可以通过创建的OPCGroup对象调用IOPCItemMgt接口增加实际数量的Item对象;即创建OPCItem对象;接着通过调用OPCGroup对象的IOPCSyncIO接口成员函数Read和Write同步读写该组所包含的Item对象的属性,即实际数据值;最后OPC客户在退出时释放所有的接口并依次删除OPCItem、OPCGroup和OPCServer对象。
    客户端程序与OPC数据存取服务器连接的过程:
    步骤1:初始化COM库。
    hr=CoInitialize(NULL);
    if(FAILED(HR))
    {
       AfxMessageBox(“CoInitialize fail!”)
               return true;
     }
    …….
    CoUninitialize();
    return FALSE;
    步骤2:创建Server对象(以下代码均略去变量定义、出错处理等部分)。
    CLSIDFromProgID(PROGRAM_ID,&clsid);
    HRESULT hr=CoCreateInstance   (clsid,NULL,CLSCTX_INPROC_SERVER,IID_IUnknown,reinterpret_cast<void**>(&m_pUnknown));
    if(FAILED(hr))
    MessageBox(“can't create server”);
    return TRUE;
    步骤3:获得IOPCServer 接口。
    m_pUnknown->QuertyIterface(IID_IOPCServer,( void**)(&m_pServer));
    步骤4:添加组
    m_pServer->AddGroup(“GROUP”,TURE,CLIENT_RATE,1,NULL,NULL,O,&m_hGroup,&revisedUpdateRate,ID_IOPCItemMgt,(LPUNKNOWN*)(&m_pItemMgt));
    步骤5:添加其他接口
    m_pItemMgt->QueryInterface(IID_IOPCSyncIO, ( void**)(&m_pSyncIO));
    m_pItemMgt->QueryInterface(IID_IOPCASyncIO, ( void**)(&m_pASyncIO));
    利用IOPCServer接口,可以实现增加或删除组对象等管理功能;利用IOPCItemMgt接口在组中可以实现增加(IOPCItemMgt::AddItems()、删除(IOPCItemMgt::DeleteItems())及管理项等功能,利用IOPCSyncIO和IOPCASyncIO可进行数据的同步或异步读写操作,不多赘述。
2.2 通过创建包装类实现客户端
    利用#import伪指令引入类型库,编辑器从类型库中读取信息并且创建包装类。不仅可以对类型库文件(.tlb)使用#import指令,也可以对组件DLL或EXE文件,甚至支持类型库的复合文件和LoadTypeLib函数可以理解的任何其他文件格式使用#import指令。#import指令将产生两个文件,他们位于输出路径,和类型库具有相同的名称,后缀分别为“.tlh”和“.tli”。用#import指令引入类型库时,在StdAfx.h文件中添加:#import “...\...\OPCServer\OPCServer.tlb”\,其他步骤代码类似COM库函数开发方式。
    包装类封装了COM库函数,Visual C++客户程序通过包装类访问组件提供的属性和方法。虽然中间多了一层,但对客户程序开发人员来说,却方便多了。#import指令利用了一个新的类:_com_ptr_t,也被成为智能指针,是一个模板类,它封装了接口指针并提供了一些方法和重载操作符来简化指针的操作。智能指针自动执行COM的CoCreateInstance和QuertyIterface、AddRef和Release函数。要实现异常处理,可使用try/catch块。在catch块中,异常对象类型为_com_error对象。_com_error类封装了HERSULT错误代码和IerrorInfo接口提供的相关环境信息。用#import伪指令,使得在Visual C++中使用代码组件和在VBA中一样方便,而且不需要在工程中对组件进行源代码维护。
2.3 利用第三方的动态连接库或工具包快速开发OPC客户端

上一篇:RS-485网络故障查找与排除 下一篇: S7 PLC与WINCC的MPI通讯

苏州瑞帕电子科技有限公司:www.isch.com.cn

脚注信息
版权所有 Copyright(C)2002-2018 苏州瑞帕电子科技有限公司