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);

}

 

4.连接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;

 

5.断开OPC服务器连接

调用COM组件的Release接口,示例代码:

m_pIServer->Release();

 

6.遍历指定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)

{

}

 

7.遍历服务器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);

 

}

8.数据项ITEM读取

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

 

9.总结

逻辑过程:

连接OPC服务器->得到服务器数据项->建立自定义组->将需要的服务器数据项加入到组中->取得项的存取接口->读写数据

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值