OPC客户端开发过程整理


2013-09-02 17:01:44|  分类: window其它 |  标签:opc客户端  opc开发   |举报 |字号 订阅

OPC开发过程:
1.注册OPC接口组件
2.通过COM接口创建OPCServerList的接口指针
CoCreateInstance只能遍历本机,CoCreateInstanceEx可遍历远程机器OPC
CLSID_OPCServerList={0x13486D51, 0x4821, 0x11D2, { 0xA4, 0x94, 0x3C, 0xB3, 0x06, 0xC1, 0x00, 0x00 } };
IOPCServerList *pIOPCServerList = NULL;
CoCreateInstance(CLSID_OPCServerList, NULL, CLSCTX_SERVER, IID_IOPCServerList, (void **)&pIOPCServerList);
3.枚举OPC服务列表
通过IOPCServerList接口EnumClassesOfCategories方法,示例:
unsigned long c;
IEnumGUID *pIEnumGUID;
CLSID catid = CATID_OPCDAServer20;
pIOPCServerList->EnumClassesOfCategories(1, &catid, 1, &catid, &pIEnumGUID);
while(S_OK == pIEnumGUID->Next(1, &clsid, &c))
{
   char buf1[256]={0}, buf2[256]={0};
   LPOLESTR progID, pOPCName;
   pIOPCServerList->GetClassDetails(clsid, &progID, &pOPCName);
   WideCharToMultiByte(CP_ACP, 0, progID, -1, buf1, 256, NULL, NULL);
   WideCharToMultiByte(CP_ACP, 0, pOPCName, -1, buf2, 256, NULL, NULL);
   printf("OPC服务器: %s, %s\n", buf1, buf2);
}

3.连接OPC服务器
通过progID获取OPC服务器CLSID,利用CLSIDFromProgID()函数。
CoCreateInstanceEx启动远程OPC服务器,COSERVERINFO结构中的远程主机名称填IP和计算机全名称都可以,代码示例:
COSERVERINFO tCoServerInfo;
MULTI_QI m_arrMultiQI; // array of interfaces we will query for each server
m_arrMultiQI.pIID = &IID_IOPCServer;
IOPCServer *m_pIServer;
CoCreateInstanceEx (
clsid, // CLSID
NULL, // No aggregation
CLSCTX_REMOTE_SERVER, // connect to remote servers
&tCoServerInfo, // remote machine name 
sizeof (m_arrMultiQI) / sizeof (MULTI_QI), // number of IIDS to query
&m_arrMultiQI);
m_pIServer = (IOPCServer *)m_arrMultiQI.pItf;

4.断开OPC服务器连接
调用COM组件的Release接口,示例代码:
m_pIServer->Release();

5.遍历指定OPC服务上的Group
连接上指定OPC服务器后,可取得服务器状态,调用GetStatus(),结果存放在OPCSERVERSTATUS结构中。
遍历GROUP:
a.通过IOPCServer接口的CreateGroupEnumerator()创建IEnumUnknown以Group对象方式遍历Group,通过IEnumUnknown获取Group存取对像接口IOPCGroupStateMgt,
调用GetState返回此Group信息,示例代码:
IEnumUnknown *pEnum = NULL;
hr = m_pIServer->CreateGroupEnumerator (
eScope, IID_IEnumUnknown, (IUnknown**)&pEnum);
IUnknown *pIUnknown;
ULONG uFetched;
IOPCGroupStateMgt *pIGroupStateMgt = NULL;
// Loop over enumerated groups (call enemerator's next member to
// reference next group and return its IUnknown interface):
while ((hr = pEnum->Next (1, &pIUnknown, &uFetched)) == S_OK)
{
// Get group state management interface of current group:
hr = pIUnknown->QueryInterface (IID_IOPCGroupStateMgt, (void**)&pIGroupStateMgt);

// Declare some variable needed to get the group name
// from the server:
OPCHANDLE hClient;
OPCHANDLE hServer;
WCHAR *pszName;

// Get group state (we are only interested in the group name):
hr = pIGroupStateMgt->GetState (
&m_dwUpdateRate,
&m_bActive,
&pszName, 
&m_lBias,
&m_fDeadband,
&m_dwLanguageID,
&hClient,
&hServer);
}
b.通过IOPCServer接口的CreateGroupEnumerator()创建IEnumString以Group名方式遍历Group,示例代码:
IEnumString *pEnum = NULL;
hr = m_pIServer->CreateGroupEnumerator (
eScope, IID_IEnumString, (IUnknown**)&pEnum);
LPOLESTR pGroupName;
ULONG uFetched;

// Loop over enumerated groups (call enemerator's next member to
// reference next group and return its name string):
while ((hr = pEnum->Next (1, &pGroupName, &uFetched)) == S_OK)
{
}

6.遍历服务器Item项
通过OPCServer获取IOPCBrowseServerAddressSpace接口,调用BrowseOPCItemIDs方法,示例代码:
IOPCBrowseServerAddressSpace *pIOPCBrowseServerAddressSpace=NULL;
pIOPCServer->QueryInterface(IID_IOPCBrowseServerAddressSpace, (void **)&pIOPCBrowseServerAddressSpace);
LPENUMSTRING pPENUMSTRING;
hr = pIOPCBrowseServerAddressSpace->BrowseOPCItemIDs(OPC_BRANCH, L"", VT_EMPTY, 0, &pPENUMSTRING);

IOPCItemProperties *pIOPCItemProperties=NULL;
pIOPCServer->QueryInterface(IID_IOPCItemProperties, (void **)&pIOPCItemProperties);

ULONG count=0;
LPOLESTR pItemName, pItemID;
while(pPENUMSTRING->Next(1, &pItemName, &count) == S_OK)
{
char bufName[256]={0};
WideCharToMultiByte(CP_ACP, 0, pItemName, -1, bufName, 256, NULL, NULL);
printf("ITEM_NAME: %s\n", bufName);
pIOPCBrowseServerAddressSpace->GetItemID(pItemName, &pItemID);
WideCharToMultiByte(CP_ACP, 0, pItemID, -1, bufName, 256, NULL, NULL);
printf("ITEM_ID: %s\n", bufName);
DWORD dwCount;
DWORD *dwPropertyIDs;
LPWSTR *ppDescriptions;
VARTYPE *ppvtDataTypes;
VARIANT *ppvData;
HRESULT *ppErrors;
pIOPCItemProperties->QueryAvailableProperties(pItemID, &dwCount, &dwPropertyIDs, &ppDescriptions, &ppvtDataTypes);
pIOPCItemProperties->GetItemProperties(pItemID, dwCount, dwPropertyIDs, &ppvData, &ppErrors);

}
7.数据项ITEM读取
通过组Group取得ITEM项存取接口(IOPCSyncIO,IID_IOPCAsyncIO等),调用Write和Read方法。

8.总结
逻辑过程:
连接OPC服务器->得到服务器数据项->建立自定义组->将需要的服务器数据项加入到组中->取得项的存取接口->读写数据
  • 0
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值