C++开发OPC客户端 点击:0 | 回复:9



二十四桥明月夜

    
  • 精华:3帖
  • 求助:0帖
  • 帖子:144帖 | 3595回
  • 年度积分:0
  • 历史总积分:7752
  • 注册:2008年3月16日
发表于:2008-08-11 09:20:11
楼主
OPC客户端应用程序的C++实现

在Visual C++或C++BUILDER环境中实现OPC客户应用程序,首先必须从OPC国际基金会官方网站下载OPC头文件("opcda_i.c"、"opcda.h" 、"opccomn_i.c"、"opccomn.h"),并在Visual C++工程的“Tool”→“Options”→“Directories”加载头文件。然后再进行登陆COM、连接服务器、数据读写等操作。在实际开发中,本文创建一个OPC通信类COPCComm,在需要通信的地方定义COPCComm类对象,然后进行相应的读写操作,其实现流程如图6所示: 


下面详细介绍通信类COPCComm的创建过程,并给出关键源代码:
 1 创建OPCComm.h
第一步:在OPCComm.h中预定义_WIN32_DCOM,
#ifndef _WIN32_DCOM
#define _WIN32_DCOM
#endif
包含如下头文件:"opcda_i.c"、"opcda.h"、 "opccomn_i.c"、"opccomn.h"
第二步:申明Iunknown、IOPCServer、IOPCItemMgt、IOPCSyncIO等关键变量为公共变量(public):
字串8

IUnknown *pUnknown;
IOPCServer *pServer;
IOPCItemMgt *pOPCItemMgt;
IOPCSyncIO *pOPCSync;
HRESULT *pErrors;
3.4.2创建OPCComm.cpp
第一步:在构造函数COPCComm::COPCComm()中登录COM。
函数CoInitislize()可以完成此功能。从函数CoGetMalloc()得到一个指向COM内存管理接口的指针。
HRESULT rl;
rl =CoInitialize(NULL);
rl =CoGetMalloc(MEMCTX_TASK,&g_pIMalloc);
第二步:添加函数HRESULT COPCComm::ConnectToServer(LPOLESTR ProgID, BOOL IsRemote, IUnknown **ppUnknown),并在函数中实现两个功能:
(1) 将ProgID变换CLSID,每COM服务器有一个字符串类型的ProgID,通过它可以得到全球唯一CLISID。用CLSIDFromProgID()函数可以实现该转换。
CLSID OPCCLSID;
HRESULT hRet=CLSIDFromProgID(ProgID,&OPCCLSID);
//如本系统中ProgID的值是“RSI.RSView 32OPCTagServer”。
(2) 建立与OPC服务器的连接,CoCreateInstance()函数创建一个OPC Sever类实例,其CLSID值设定如下:
hRet=CoCreateInstance(OPCCLSID,NULL,CLSCTX_LOCAL_SERVER,IID_IUnknown,(void **)ppUnknown);
字串2

return hRet;
该段程序的结果是得到一个指向服务器对象Iunkown接口的指针变量ppUnknown。
第三步:添加函数int COPCComm::Initial Communication(),并在函数中实现如下几步:
(1) 请求其他接口指针:
从Iunkown接口,通过QueryInterface()方法得到一个指向服务器对象IOPCSever接口的指针变量pServer:
hRet=pUnknown->QueryInterface(IID_IOPCServer,(void **)&pServer);
// 得到一个指向服务器对象IOPCSVerser接口的指针(变量pServer)。
(2) 创建OPC组,
用IOPCSever接口方法AddGroup()实现:
hRet=pServer->AddGroup(L"",TRUE,500,1235,&lTimeBias,&fTemp,0,&hOPCServerGroup, &dwActualRate,IID_IUnknown,&pUnknown);
// 创建一个有指向名称和属性的组。在返回的参数中,有一个指向所需要的进程组对象IOPCItemMgt接口的指针(变量pUnknown )。
(3) 添加项:用IOPCItemMgt接口的AddItems()方法添加具有特殊属性的指定数量的项:
hRet=pOPCItemMgt->AddItems(ItemNumber,ItemArray,(OPCITEMRESULT**)&pItemResult,(HRESULT **)&pErrors);
(4) 用OPC项执行所需的操作,本系统采用同步通信,就需要指向IOPCSyncIO接口指针。
字串8


hRet=pUnknown->QueryInterface(IID_IOPCSyncIO,(void **)&pOPCSync);
第四步:添加COPCComm::ReadFromRsview(int AIItemNumber, float fData【】),实现读取数据。
HRESULT hRet;
hRet=pOPCSync->Read(OPC_DS_CACHE, AIItemNumber, hServerAI, &pItemValue, &pErrors);
// OPC项的数据被送到客户程序的IadviseSink接口。
for(int i=0;i<AIItemNumber;i++)
fData【i】=V_R4(&pItemValue【i】.vDataValue);
其中,AIItemNumber为一次读入数据的总个数,pItemValue为服务器保存数据的数组,fData为客户端读取数据的数组。
第五步:添加COPCComm::WriteRsview(CString strSend, int iMark),实现数据写入。
COleVariant WriteValue;
HRESULT hRet;
WriteValue = strSend;// strSend为待写的数据
WriteValue.ChangeType(VT_R4);
hRet=pOPCSync->Write(1, &hServerAO【iMark】, WriteValue, &pErrors);
//写一个值,iMark表示执行器标号,可由用户自己定义。
第六步:在析构函数~COPCComm()中销毁对象,释放内存,在程序停止运行之前,必须删除已创建的OPC对象并释放内存。
pOPCSync->Release(); 字串9
pOPCItemMgt->Release();
pServer->Release();
pUnknown->Release();
创建完通讯类后,则可以在需要通信的地方,调用相应的函数(方法)即可。
4 结束语
OPC规范把硬件供应系统和软件开发者分离开来,使得软件开发者不需要过多的了解硬件的实质和操作过程,只要遵循OPC规范进行开发,就可以访问OPC服务器的数据。本文介绍的VC++环境下的客户端应用程序,能够发挥OPC的最佳性能,完全满足过程控制领域对数据实时、高效的要求。




二十四桥明月夜

  • 精华:3帖
  • 求助:0帖
  • 帖子:144帖 | 3595回
  • 年度积分:0
  • 历史总积分:7752
  • 注册:2008年3月16日
发表于:2008-08-11 15:52:07
1楼

没人感兴趣呀,

看到这段代码,许多人头就晕了,但对我来说,很有用;

 

死亡骑士

  • 精华:0帖
  • 求助:0帖
  • 帖子:7帖 | 1774回
  • 年度积分:0
  • 历史总积分:2635
  • 注册:2006年7月17日
发表于:2008-08-12 13:27:25
2楼

这样的帖子不加精,什么才算精?

wdl4191906

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 30回
  • 年度积分:0
  • 历史总积分:42
  • 注册:2007年11月04日
发表于:2008-08-15 21:48:42
3楼

果然是 经典啊

                   狂顶

刘梦奇

  • 精华:0帖
  • 求助:0帖
  • 帖子:4帖 | 1回
  • 年度积分:0
  • 历史总积分:13
  • 注册:2007年12月25日
发表于:2008-08-21 08:58:32
4楼

数据桥(vc++)通过opcserver可以把数据读取出来. 请高手指点如何读取数据,并把相应的最大,最小值;报警值;单位等相关信息取出来.


或提供些函数,接口,相关资料.

tweety

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 78回
  • 年度积分:0
  • 历史总积分:362
  • 注册:2003年4月01日
发表于:2008-09-03 13:16:58
5楼

tweety

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 78回
  • 年度积分:0
  • 历史总积分:362
  • 注册:2003年4月01日
发表于:2008-09-03 13:17:11
6楼

阿一

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 3回
  • 年度积分:0
  • 历史总积分:53
  • 注册:2007年10月29日
发表于:2008-09-03 17:01:14
7楼

毕业设计要做OPC,真是无从下手,头疼得很

看到这个帖子真的是看到了一丝希望

小心触电

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 10回
  • 年度积分:0
  • 历史总积分:59
  • 注册:2008年9月05日
发表于:2008-09-05 19:34:11
8楼
l楼主!能告诉我什么是二线制?什么是四线制?本人刚刚触及PLC,还不太懂

ZHANGHONG7610

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 1回
  • 年度积分:0
  • 历史总积分:1
  • 注册:2004年5月13日
发表于:2009-04-17 16:41:47
9楼

thanks!!!!!!!!!!!


相关主题

官方公众号

智造工程师