OPC工作记录整理——第六篇(同步读取和异步读取)
2015-01-30 21:14
477 查看
笔者博客里曾经转载过一篇关于OPC同步读取、异步读取和OPC订阅的区别的博客,其中讲的比较详细,笔者就不再过多的赘述这些内容,总之,同步读取是客户端在发出读取请求之后,需要等待服务器的响应,服务器给出回应之后,客户端才能够进行下一步的操作,而异步读取时,客户端发出请求之后,立马执行下一步的程序,当服务器给出回应之后,客户端才进行读取数据的操作。
总而言之,同步读取读取的结果直接在主程序中存入了数组中,而异步读取的结果是通过一个IOPCDataCallback的类中,有一个继承的方法叫OnReadComplete,异步读取的结果就从这个方法中返回。而这个IOPCDataCallback的类往往是用来进行OPC的数据订阅方法的读取的,所以说,数据订阅往往伴随着异步读取的方式。
下面就来看同步读取的代码。
首先是获取数据项服务句柄:
然后是获取同步读取指针IOPCSyncIO,注意不是IOPCAsyncIO,笔者之前就是把这个接口搞错了,所以一直没有获取到数据。根据笔者的印象,前者应该是后者的升级,好像是在OPC2.0接口中才有的。
总而言之,同步读取读取的结果直接在主程序中存入了数组中,而异步读取的结果是通过一个IOPCDataCallback的类中,有一个继承的方法叫OnReadComplete,异步读取的结果就从这个方法中返回。而这个IOPCDataCallback的类往往是用来进行OPC的数据订阅方法的读取的,所以说,数据订阅往往伴随着异步读取的方式。
下面就来看同步读取的代码。
首先是获取数据项服务句柄:
hOPCServer2[0] = (OPCHANDLE)pItemResult[0].hServer;
然后是获取同步读取指针IOPCSyncIO,注意不是IOPCAsyncIO,笔者之前就是把这个接口搞错了,所以一直没有获取到数据。根据笔者的印象,前者应该是后者的升级,好像是在OPC2.0接口中才有的。
IOPCSyncIO *pIOPCSyncIO = NULL; //第十个指针,指向同步读取 hr = pIOPCItemMgt->QueryInterface(IID_IOPCSyncIO, /*OUT*/ (void**)&pIOPCSyncIO); if (FAILED(hr)) { cout << "未能获取到接口IOPCSyncIO" << endl; if (pItemResult) CoTaskMemFree(pItemResult); if (pErrors) CoTaskMemFree(pErrors); if (pIOPCSyncIO) CoTaskMemFree(pIOPCSyncIO); CoTaskMemFree(&hOPCServer1); CoTaskMemFree(&hOPCServer2); if (pIServer) pIServer->Release(); pIServer = NULL; if (pIUnknown) pIUnknown->Release(); pIUnknown = NULL; if (pIEnumGUID) pIEnumGUID->Release(); pIEnumGUID = NULL; if (pIServerList) pIServerList->Release(); pIServerList = NULL; if (pIOPCItemMgt) pIOPCItemMgt->Release(); pIOPCItemMgt = NULL; return 1; } else if (SUCCEEDED(hr)) { ASSERT(pIOPCSyncIO); cout << "已获取到接口IOPCSyncIO" << endl; }同步读取的代码:
DWORD dwItemNumber = 1; OPCITEMSTATE *pItemValue = NULL; //第十二个指针,指向读取OPC SERVER的值 hr = pIOPCSyncIO->Read(OPC_DS_CACHE, dwItemNumber, hOPCServer2, &pItemValue, &pErrors); if (FAILED(hr)) { cout << "未能读取到OPC服务器端相对应的数据,请查看数据源是否有误" << endl; if (pItemResult) CoTaskMemFree(pItemResult); if (pErrors) CoTaskMemFree(pErrors); if (pIOPCSyncIO) CoTaskMemFree(pIOPCSyncIO); CoTaskMemFree(&hOPCServer1); CoTaskMemFree(&hOPCServer2); CoTaskMemFree(&pItemValue); if (pIServer) pIServer->Release(); pIServer = NULL; if (pIUnknown) pIUnknown->Release(); pIUnknown = NULL; if (pIEnumGUID) pIEnumGUID->Release(); pIEnumGUID = NULL; if (pIServerList) pIServerList->Release(); pIServerList = NULL; if (pIOPCItemMgt) pIOPCItemMgt->Release(); pIOPCItemMgt = NULL; VariantClear(&pItemValue[0].vDataValue); return 1; //同步读数据时出错 } else if (SUCCEEDED(hr)){ ASSERT(hr); cout << "已读取到OPC服务器端的数据" << endl; cout << V_R4(&pItemValue[0].vDataValue) << endl; //输出数据 }异步读取其实与同步读取类似,异步读取需要获取的接口是IOPCAsyncIO2,注意不是IOPCSyncIO2,IOPCSyncIO2是IOPCAsyncIO2的升级。
hr = pIOPCItemMgt->QueryInterface(IID_IOPCAsyncIO2, /*OUT*/(void**)&pIOPCAsyncIO2); //得到第十一个指针 ASSERT(pIOPCAsyncIO2); if (FAILED(hr)) { cout << "未能获取到接口IOPCSyncIO2..." << endl; if (pItemResult) CoTaskMemFree(pItemResult); if (pErrors) CoTaskMemFree(pErrors); CoTaskMemFree(&hOPCServer1); CoTaskMemFree(&hOPCServer2); //第六个内存释放 CoTaskMemFree(&itemArray); //第五个内存释放 CoTaskMemFree(&clsid); //第四个内存释放 CoTaskMemFree(&catID); //第三个内存释放 CoTaskMemFree(&mqi); //第二个内存释放 CoTaskMemFree(&si); //第一个内存释放 if (pIOPCAsyncIO2) pIOPCAsyncIO2->Release(); //第十一个指针释放 pIOPCAsyncIO2 = NULL; if (pIOPCGroupStateMgt) pIOPCGroupStateMgt->Release(); //第十个指针释放 pIOPCGroupStateMgt = NULL; if (pIOPCItemMgt) pIOPCItemMgt->Release(); //第五个指针释放 pIOPCItemMgt = NULL; if (pIServer) pIServer->Release(); //第四个指针释放 pIServer = NULL; if (pIUnknown) pIUnknown->Release(); //第三个指针释放 pIUnknown = NULL; if (pIEnumGUID) pIEnumGUID->Release(); //第二个指针释放 pIEnumGUID = NULL; if (pIServerList) pIServerList->Release(); //第一个指针释放 pIServerList = NULL; return 1; } else if (SUCCEEDED(hr)) { cout << "已获取到接口IOPCSyncIO2..." << endl; }异步读取的代码:
DWORD dwItemNumber = 1; DWORD dwCancelID; OPCITEMSTATE *pItemValue = NULL; //第十二个指针,指向读取OPC SERVER的值 hr = pIOPCAsyncIO2->Read(dwItemNumber, hOPCServer2, 1, &dwCancelID, &pErrors); //异步读取,数据在COPCDataCallback中返回 if (FAILED(hr)) { cout << "未能读取到OPC服务器端相对应的数据,请查看数据源是否有误..." << endl; VariantClear(&pItemValue[0].vDataValue); if (pItemResult) CoTaskMemFree(pItemResult); if (pErrors) CoTaskMemFree(pErrors); CoTaskMemFree(&hOPCServer1); CoTaskMemFree(&hOPCServer2); //第六个内存释放 CoTaskMemFree(&itemArray); //第五个内存释放 CoTaskMemFree(&clsid); //第四个内存释放 CoTaskMemFree(&catID); //第三个内存释放 CoTaskMemFree(&mqi); //第二个内存释放 CoTaskMemFree(&si); //第一个内存释放 if (pIOPCAsyncIO2) pIOPCAsyncIO2->Release(); //第十一个指针释放 pIOPCAsyncIO2 = NULL; if (pIOPCGroupStateMgt) pIOPCGroupStateMgt->Release(); //第十个指针释放 pIOPCGroupStateMgt = NULL; if (pIOPCItemMgt) pIOPCItemMgt->Release(); //第五个指针释放 pIOPCItemMgt = NULL; if (pIServer) pIServer->Release(); //第四个指针释放 pIServer = NULL; if (pIUnknown) pIUnknown->Release(); //第三个指针释放 pIUnknown = NULL; if (pIEnumGUID) pIEnumGUID->Release(); //第二个指针释放 pIEnumGUID = NULL; if (pIServerList) pIServerList->Release(); //第一个指针释放 pIServerList = NULL; return 1; //读数据时出错 } else if (SUCCEEDED(hr)) { cout << "已获取到数据..." << endl; }异步读取的结果返回将在下一篇介绍数据订阅读取方式时再做介绍。
相关文章推荐
- OPC工作记录整理——第二篇(OPC客户端运行环境配置)
- OPC工作记录整理——第四篇(OPC客户端开发之OPC服务器的枚举和连接)
- OPC工作记录整理——第一篇(序)
- OPC工作记录整理——第三篇(开发环境的配置)
- OPC工作记录整理——第七篇(数据订阅)
- OPC工作记录整理——第五篇(添加组和添加项)
- OPC同步读取和异步读取-------OPC(第七篇)
- OPC的数据访问方法分别有同步访问、异步访问和订阅式
- 整理一下之前工作中记录过的一些东西——sequence:在这里可以解释为"序列"
- 整理一下之前工作中记录过的一些东西——4gl
- socket网络编程之路 第六篇 -----同步与异步,阻塞与非阻塞的区别
- 工作记录整理
- 经典设计整理之二——————异步复位,同步释放
- 整理一下之前工作中记录过的一些东西——shell
- 阻塞、非阻塞与异步、同步(转载+整理)
- boost asio库中同步、异步工作机制
- SerialPort 同步和异步数据读取
- 整理一下之前工作中记录过的一些东西——交强险无赔优
- 工作学习记录----Struct的数据读取
- Winsock工作模型 同步 异步