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伺服器->得到伺服器資料項->建立自定義組->將需要的伺服器資料項加入到組中->取得項的存取介面->讀寫資料
相關文章
- OPC客戶端開發工具WTopcclient補充說明客戶端client
- 「美餐客戶端 3.0」設計過程客戶端
- .net socket.io客戶端使用過程客戶端
- 開發JAXR客戶端客戶端
- 走近原始碼:Redis命令執行過程(客戶端)原始碼Redis客戶端
- nginx 處理客戶端請求的完整過程Nginx客戶端
- 騰訊 客戶端開發 QT客戶端QT
- Fabric1.4原始碼解析:客戶端建立通道過程原始碼客戶端
- 使用 .NET MAUI 開發 ChatGPT 客戶端UIChatGPT客戶端
- Flutter混合開發玩Android客戶端FlutterAndroid客戶端
- 使用Flutter開發Github客戶端及學習歷程的小結FlutterGithub客戶端
- Dubbo-go 原始碼筆記(二)客戶端呼叫過程Go原始碼筆記客戶端
- 青芒 for Mac客戶端開發筆記Mac客戶端筆記
- 網路開發基礎客戶端001客戶端
- 客戶端的js js指令碼的引入 js的解析過程客戶端JS指令碼
- Swoole 協程 MySQL 客戶端與非同步回撥 MySQL 客戶端的對比MySql客戶端非同步
- flutter開發的乾貨集中營客戶端Flutter客戶端
- 使用BindingX開發客戶端炫酷動畫客戶端動畫
- 頭條Android客戶端開發面經分享Android客戶端
- Java服務端和客戶端開發輔助工具UtilsJava服務端客戶端
- 使用 Flutter 開發知識小集 iOS/Android 客戶端FlutteriOSAndroid客戶端
- Hyperledger fabric-SDK-GO客戶端開發篇(六)Go客戶端
- Django透過request獲取客戶端IPDjango客戶端
- TCP程式設計之服務端和客戶端的開發TCP程式設計服務端客戶端
- Kubernetes客戶端認證(三)—— Kubernetes使用CertificateSigningRequest方式簽發客戶端證書客戶端
- OAuth客戶端開源JDK:AppAuthOAuth客戶端JDKAPP
- 如何開啟客戶端加密特性客戶端加密
- 如何在跟進過程中打動客戶?
- C++20協程例項:攜程化的IOCP服務端/客戶端C++服務端客戶端
- dubbo客戶端客戶端
- Pulsar客戶端客戶端
- mqtt 客戶端MQQT客戶端
- 外貿客戶開發
- Flutter 開發一個 GitHub 客戶端 | 掘金技術徵文FlutterGithub客戶端
- 「完整案例」基於Socket開發TCP傳輸客戶端TCP客戶端
- 服務端,客戶端服務端客戶端
- 客戶端,服務端客戶端服務端
- Nacos - 客戶端心跳續約及客戶端總結客戶端
- java web 通過request獲取客戶端IPJavaWeb客戶端