日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OPC通讯开发——客户端开发工具WTopcclient说明手册部分翻译及个人补充

發布時間:2023/12/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OPC通讯开发——客户端开发工具WTopcclient说明手册部分翻译及个人补充 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

?? 經過多個月的開發、現場測試和反饋修改,自己開發的OPC客戶端終于真正能在現場使用了。由于工業現場的服務器很古老,只支持OPCDA架構,我們也只能按照DA的標準設計客戶端。由于有著WTopcclient這個相對好用的客戶端開發工具,在開發方面花費的精力還好,可是卻苦了現場的同學,在DCOM配置上花費了不少功夫╮(╯-╰)╭,在這里向他們表示最高的敬意。
?? 言歸正傳,WTopcclient在使用中,我幾乎找遍了整個百度,真正有用的除了人家在.h里函數聲明處加的注釋,就只剩下一個英文說明書了,除此之外幾乎沒有任何有價值的資料,為此開發OPC客戶端中也遇到不少坑,下面把自己的一些經驗總結一下,方便以后的開發(當然,如果以后OPCUA普及的話,就再也不用這么費勁的整一個上個世紀的玩意了)。下面對OPCclient的頭文件和官方英文說明書中的內容進行潤色翻譯,并結合自己的備注額外補充一些說明,防止以后使用再踩這些坑。
創作不易,轉載請您注明出處,感謝您的支持。

一、手冊前言

備注:全文中如有“應用程序”字樣,全部指的是“由開發者依據這個DLL開發的OPC客戶端應用程序”

譯文:
WTclient DLL 使用手冊
?? WinTECH軟件快速客戶端開發DLL(WTclient)提供了一套很簡單就可以使用的API,用于將用戶開發的OPC客戶端應用程序與來自任何OPC服務器的數據建立連接。COM和OPC的所有細節由DLL自己處理,所以開發應用程序時很簡單地就可以從服務器獲取數據點,而不必關心底層接口的實際實現。在OPC通訊中所有必需的OPC接口,本DLL都支持OPC1.0和OPC 2.0數據訪問標準以及瀏覽接口,并支持連接到簡單的報警和事件服務器。 該使用手冊應配合OPC數據訪問和OPC警報和事件規范文件(規范文件是OPC基金會官方定義的有關OPC的標準,可從基金會官網http://www.opcfoundation.org中獲得)。

制作自己的OPC客戶端程序
使用 WTclient.DLL 關聯WTclient.lib 到項目中
?? WTclient.lib包含了DLL中 API函數的導出定義。將此文件包含在自己開發的OPC客戶端應用程序的項目文件中,并將WTclientAPI.h包含在將要調用DLL的模塊中。
備注:在這個頭文件中有lib中函數的聲明,可以看到函數調用和返回的參數,以及對函數的注釋
譯文:
初始化DCOM
?? 從WTClient.DLL版本2.0開始,現在由客戶端應用程序負責正確初始化DCOM。在版本2.0之前,WTClient.dll在DLLMain函數中執行DCOM和安全初始化,并在卸載dll時調用CoUninitialize()。由于各種Windows dll的加載順序不同,這樣會出現一些問題,所以現在這些初始化調用被移到一個新的導出函數WTclientCoInit( )中,客戶端應用程序可以在主線程啟動期間調用該函數。WTclientCoInit()將DCOM初始化為多線程,并使用默認安全性。您所開發的OPC客戶端應用程序也可以選擇自己進行DCOM初始化,而不使用函數WTclientCoInit( )。無論是否調用API函數進行DCOM初始化,應用程序在終止時都必須調用CoUninitialize()。
備注:可以看到,如果想簡單通過MFC或Qt開發一個OPC客戶端,在程序開始時必須WTclientCoInit()初始化才可以正常使用DCOM,程序結束時必須調用CoUninitialize()。需要注意一下,在WTclientAPI.h中還聲明了一個WTclientCoUninit()函數,且注釋里說這個函數用來取消DCOM初始化,但說明書里并沒有提到這個函數- -。CoUninitialize()這個是windows提供的頭文件中取消初始化的函數,與COM和OLE有關系,OPC是過程控制中使用的OLE嘛,所以OPC基礎還是COM和OLE沒毛病。

二、手冊正文部分函數翻譯和說明

譯文:
獲取 OPC 服務器列表
?? WTclient.dll 提供了兩個函數來使客戶端應用程序可以獲取可用的OPC Servers列表.

int NumberOfOPCServers(BOOL UseOPCENUM, LPCSTR MachineName);

?? OPCENUM是OPC基金會提供的一個組件,它允許客戶端應用程序獲取本地或遠程計算機上可用服務器的列表(注:OPCENUM顧名思義,會枚舉指定計算機擁有OPC服務器的數量)。很遺憾在編寫組件時,OPCENUM的操作沒有很好的跨平臺一致性。所以WTclient.dll允許應用程序使用OPCENUM組件獲取服務器列表,或通過掃描Windows注冊表的本地副本繞過OPCENUM并獲取服務器列表。如果可以使用OPCENUM的話,你可以傳遞一個遠程計算機的名稱(其實指的是它的IP地址)來獲取遠程OPC服務器列表。
頭文件注釋翻譯:
?? NumberOfOPCServers(…)
?? 返回可用OPC服務器的數量,如果UseOPCENUM為FALSE,服務器列表從本地Windows注冊表獲取,忽略MachineName;如果UseOPCENUM為真,服務器列表是從OPCENUM組件獲取的,由OPC基金會和MachineName提供,從遠程計算機獲取服務器列表。
備注: 實際上之所以OPC服務器端初始化有個步驟叫“注冊服務器”,就是因為它是在計算機注冊表里注冊了OPC服務器的信息
功能:獲取服務器數量
參數:BOOL UseOPCENUM 是否使用OPCENUM來枚舉服務器
?? LPCSTR MachineName 計算機名,本地服務器為空,遠程服務器為IP地址
返回值:int 返回查詢到的服務器數量
?? 連接遠程服務器,一定要注意DCOM的配置,這是非常麻煩的一件事,本地服務器相對配置就非常簡單(幾乎不需要配置)。

譯文:
?? 從WTclient.dll返回服務器數后,應用程序可以通過調用下面函數獲取服務器名:

BOOL GetServerName(int index, LPSTR Buffer, int BufSize);

?? 由客戶端程序開發者提供一個提前定義好的字符串Buffer,調用該函數獲取的服務器名字會放在該字符串中,也可以直接使用該函數讀取指定第幾個服務器名字。BufSize標識用戶提供的字符緩沖區的長度(注:也就是說限制了獲取的服務器名字最多BufSize這么長),可以防止dll載入過長的名字。如果Buffer中返回了一個有效的服務器名稱,GetServerName函數返回TRUE,否則返回FALSE。
頭文件注釋翻譯:
??用于遍歷NumberOfServers()獲得的服務器列表
??在服務器列表索引處填充服務器名稱,放到Buffer指向的用戶緩沖區中。
??返回的值為FALSE表示索引無效。
備注:這個函數用來獲取服務器名字。一個由用戶提供的字符緩沖區Buffer負責存放傳遞過來的index標識的服務器列表中某個服務器名字。也就是說,比如調用NumberOfOPCServers()得到本地有兩個服務器,建立一個for循環就可以逐個讀取服務器名字,索引從0開始,每次執行該函數得到的服務器名字會放在Buffer中,可以使用別的變量保存每個服務器名字。
譯文:
建立與 OPC 服務器的連接

HANDLE ConnectOPC(LPCSTR MachineName, LPCSTR ServerName, BOOL EnableDLLBuffering); HANDLE ConnectOPC1(LPCSTR MachineName, LPCSTR ServerName, BOOL EnableDLLBuffering); HANDLE ConnectOPC_AE(LPCSTR MachineName, LPCSTR ServerName);

?? 如果可以通過MachineName(OPC服務器所在計算機名,本地則為空字符串,遠程則為IP地址)和ServerName(OPC服務器名字,在之前的步驟中得到)建立到指定OPC服務器的連接,那么這個函數返回一個有效的句柄HANDLE 。(這個句柄是服務器的句柄,對指定服務器的內容進行操作,都需要提供這個句柄,一定要好好保存!)客戶端程序可以同時連接多個服務器,每個服務器連接成功后都會返回這個服務器的句柄。WTclient將嘗試使用OPC 2.0連接點接口進行連接。如果不可用,它將恢復OPC 1.0 DataObject接口。
??EnableDLLBuffering如果為TRUE,DLL會自己維護客戶端應用程序創建的所有項的列表并接收服務器更新,當服務器數據改變,dll維護的這個列表會更新,應用程序要用ReadOPCItem()來讀取項的數據(本身是為了讀取OPC服務器項對應標簽的數據,實際是讀取了DLL中的列表中的對應數據,對于我們使用者來說這些細節無關緊要)。
?? 如果EnableDLLBuffering為FALSE,DLL不會保留項數據的本地副本和對的后續調用(DLL不會自己維護一個項列表),ReadOPCItem()將失敗。用戶應用程序必須定義正確的回調函數,(EnableOPCNotification()),獲取項更新,對于那些使用不支持回調函數的工具設計的應用程序(如Visual Basic 5.0),可以將WTclient配置為維護由應用程序創建的所有OPC項(標記)的列表(即上面的參數設為TRUE)。當來自服務器的數據更改時,dll列表中相應的標記值將被更新??刂茟贸绦蚩梢噪S時讀取標記的值。
?? ConnectOPC1 會一直嘗試一個 OPC 1.0 標準對OPC服務器的連接。
?? ConnectOPC_AE 將會建立一個到 OPC 報警 & 事件服務器的連接。
頭文件注釋翻譯:
ConnectOPC (…)
?? 與指定服務器建立OPC連接,如果無法建立連接,則返回INVALID_HANDLE_VALUE (-1),如果EnableDLLBuffering為真,DLL將維護應用程序創建的所有項的列表,并由服務器更新。應用程序可以根據需要使用ReadOPCItem()獲取新的項數據。如果EnableDLLBuffering為FALSE,DLL不會保留項數據和后續調用的本地副本,ReadOPCItem()將失敗。用戶應用程序必須定義正確的回調函數(EnableOPCNotification())獲取項更新。
ConnectOPC1(…)
?? 如果OPC服務器支持IConnectionPtContainer接口,那么ConnectOPC函數總會嘗試一個OPC2.0版的連接,而這個函數可以強制客戶端使用IAdvise接口來使得客戶端與服務器建立OPC1.0a標準連接。
ConnectOPC_AE (…)
?? 與指定的A&E服務器建立OPC連接,如果無法連接返回INVALID_HANDLE_VALUE (-1)。
備注: 一般來說都是使用最普通的ConnectOPC(…)函數進行OPC連接的。第一個參數在遠程連接服務器時為服務器所在IP地址,本地時傳入空字符即可,第二個參數就是連接到的OPC服務器名字,最后一個參數一般都是用TRUE,這樣就不用再費力氣去研究什么回調函數了,直接使用開發工具提供的讀寫函數就可以操作OPC項了。
譯文:

void DisconnectOPC(HANDLE hConnect); void DisconnectOPC_AE(HANDLE hConnect);

?? 當應用程序終止時,它負責與連接的服務器斷開連接。DisconnectOPC(), (或者 Disconnect_OPCAE()), 函數會將hConnect(這個句柄就是在連接到指定服務器的時候返回的句柄,斷開時也要用到,后面很多操作都需要,十分重要)定義的連接的完全關閉。
頭文件注釋翻譯:
DisconnectOPC(…)
?? 用于關閉OPC連接。
備注:用來在結束對服務器讀寫后關閉到服務器連接的,其他沒什么好說的,一定要注意這個參數填的是連接到服務器時獲取的句柄。再次強調一遍,在OPC連接中所有的句柄都非!常!重!要!千萬要好好保存。
譯文:
獲取 OPC Server 標簽名列表

int NumberOfOPCItems(HANDLE hConnect); BOOL GetOPCItemName(HANDLE hConnect, int index, char *pBuf, int BufSize);

?? NumberOfOPCItems() 返回由句柄hConnect指向的 OPC Server所擁有的標簽總數. 建立一個for循環, GetOPCItemName將會遍歷所有可用的標簽名,來讓用戶選擇要建立連接項的標簽,或者生成一個標簽名列表. NumberOfOPCItems 將從服務器瀏覽項目名稱的完整列表,并以“FLAT”格式顯示該列表。
頭文件注釋翻譯:
NumberOfOPCItems(…)
?? 從指定服務器連接的瀏覽接口返回OPC項目數,如果服務器不支持瀏覽,則返回值為xero。此函數用于填充itemnames的內部數組,這個數組通過GetOPCItemName()訪問。此函數相當于從根位置使用OPC_FLAT調用BrowseItems,NumberOfOPCItems()使用BROWSE_DOWN和BROWSE_UP遍歷樹。
GetOPCItemName(…)
?? 允許用戶從NumberOfOPCItems()迭代來獲取每個項的名字。
備注:這兩個函數使用就像之前獲取服務器名時一樣,先獲取服務器擁有的標簽item數目,通過NumberOfOPCItems返回值,然后逐個讀取標簽的名字。

BOOL GetNameSpace(HANDLE hConnect, WORD *pNameSpace); BOOL BrowseTo(HANDLE hConnect, LPCSTR NodeName); char SetWTclientQualifier(char qualifier); int BrowseItems(HANDLE hConnect, WORD Filter);

?? 為了更好地訪問具有分層名稱空間的服務器,WTClient dll提供了一些函數,允許應用程序直接從服務器瀏覽項名稱。?? SetWTclientQualifier 允許應用程序更改用于分析分層命名空間節點的定界字符??蛻舳薲ll所需的默認分隔符是“.”,但是,某些服務器使用“.”字符作為節點名的一部分。GetNameSpace允許應用程序確定服務器的命名空間。BrowseTo將當前瀏覽位置移動到指定的名稱,BrowseItems使用服務器中的節點名填充內部名稱列表。BrowseTo可用于讀取OPC_BRANCH下面的OPC_LEAF(葉子的名字),首先要用GetOPCItemName獲取OPC_BRANCH樹枝名,然后使用BrowseTo移動瀏覽位置到該樹枝名位置,然后繼續使用GetOPCItemName就可以讀取當前樹枝下的葉子名。WtClient.DLL為NumberOfOPCItems()函數和BrowseItems()函數維護一個單一的名稱列表,因此應用程序在瀏覽服務器命名空間的時候必須很小心,避免覆蓋前一次調用的值。在各個等級的樹的相互作用過程中,調用BrowseItems之后,所有的項目名稱必須立刻拷貝到本地存儲中。
使用OPC_FLAT從根位置調用BrowseItems的行為與NumberOfOPCItems()相同。
頭文件注釋翻譯:
GetNameSpace(…)
?? 從指定的服務器連接中返回OPC_NS_FLAT (2)或者OPC_NS_HIERARCHIAL (1)。
BrowseTo(…)
?? 將服務器的當前瀏覽位置更改為指定的節點,使用NULL或“Root”瀏覽到樹的頂部,NodeName應該是從GetItemName返回的完整的指定節點名。
SetWTclientQualifier(…)
?? 允許應用程序提供用于在分層命名空間中分隔標記名,分隔字符默認為"."。
BrowseItemNames(…)
?? 返回當前瀏覽位置的項數并通過GetItemName()填充具有可訪問節點名的內部項名稱數組。
?? Filter參數指定:
?? OPC_BRANCH:返回所有有孩子的項
?? OPC_LEAF:返回所有沒有孩子的項
?? OPC_FLAT:返回所有在當前位置下的OPC項名字,(LEAFS ONLY),(包括所有孩子的孩子)。
備注:一個一個函數說明,首先是GetNameSpace(…),它可以查看服務器是平面結構還是分層結構的,如果是平面,那么服務器下面直接就能列出所有的項,相當于你打開C盤,所有的txt文件都存在了C盤下面,如果是分層那么后面獲取項就稍微麻煩了,相當于你在C盤下建了很多文件夾,文件夾里可能又建了文件夾。。。服務器可能套了很多層目錄,然后你一層層展開才能找到真正的項。
?? BrowseTo(…)這個函數是切換目錄的函數,當然是很重要了!相當于linux系統下面的一次cd操作,每次遍歷完一個目錄都要用這個函數切換目錄,需要注意,如果是多層目錄,切換的時候一定要輸入目錄的全名!相當于絕對路徑(這一點上我就遇到了大坑,在OPC服務器目錄到兩層以上的時候,怎么切換目錄都切不過去,后來發現,目錄必須是全名!)
?? SetWTclientQualifier(…)這個函數用來更改解析服務器目錄的標識符,舉例說明,服務器里有個標簽叫“1.2.3”,那么默認用“.”解析,會認為這個標簽首先在樹枝1下面,然后樹枝1下面有個小樹枝2,小樹枝2下面有個樹葉3,(使用BrowseTo(…)切換到小樹枝2的時候,一定參數要填“1.2”而不是“2”!),可能有的服務器也有一個這樣結構的標簽,但比如它用“_”來分界,那么標簽全名就成了“1_2_3”,這時候就需要用到這個函數更改解析服務器層級結構的標識符了(當然,目前見到過的幾個大公司,OPC服務器都是用這個小數點,暫時沒遇到那種奇葩的標識符不用小數點的- -)。
?? BrowseItem(…)這個函數用來在BrowseTo(…)切換位置后,規定程序怎么看待當前目錄的,規定了是把這個目錄下面的東西當樹枝(目錄)看還是當葉子(真正的標簽)看,同時它的返回值返回了按照這種方式看這個目錄,下面有多少個指定的玩意。比如說,現在的目錄下面都是真正的標簽了,你還用樹枝的方式看這個目錄,那么返回的就只有0個了。所以說,其實我們開發OPC客戶端時還是用了一定先驗知識的,知道現在這層目錄下面是樹枝還是葉子,如果提前不知道,那么只能一層一層的試才能解析出來目錄結構是幾層- -。

譯文:

BOOL SetBrowseFilters(HANDLE hConnect, LPCSTR UserString, VARTYPE DataType, DWORD AccessType);

??應用程序可以設置瀏覽過濾器,以影響從服務器返回的OPC項目數。
應用程序可以選擇僅檢索具有特定數據類型或訪問權限的那些項。
UserString:只能瀏覽到包含指定字符的標簽
DataType:只能瀏覽到指定數據類型的標簽
AccessType:只能瀏覽到包含指定讀寫標志的標簽(可讀 可寫 既可讀又可寫)
頭文件注釋翻譯:
SetBrowseFilters(…)
??允許應用程序指定在瀏覽操作期間使用的篩選器。可以根據用戶定義的字符串、數據類型或讀/寫訪問權限。
備注:囧,這個開發工具真的是越用越方便,剛開始用的時候各種不順手,篩選點名都是用CString的Find來做的- -,我也是現在翻譯文檔才發現還有個專門的篩選函數QAQ,居然還可以篩權限和數據類型。
譯文:
創建 OPC 組 and 項

HANDLE AddOPCGroup(HANDLE hConnect, LPCSTR Name, DWORD *pRate, float *pDeadBand); void RemoveOPCGroup(HANDLE hConnect, HANDLE hGroup);

??WTclient.dll有兩個允許您創建和刪除OPC組的函數。函數的作用是:創建一個組后返回一個組句柄(對組內內容的操作都要通過組句柄),必要時必須提供給其他Wtclient函數。作為參數傳遞給AddOPCGroup的值由控制應用程序確定,并且特定于每個組。LPCSTR Name名稱是任意的,不能使用服務器名。DWORD *pRate是指向所需刷新率(以毫秒為單位)的指針,服務器使用該刷新率向客戶端提供更新,就是說每隔刷新率的時間,服務器向這個組內內容更新數據。
頭文件注釋翻譯:
AddOPCGroup(…)
??為定義的連接創建新的OPC組,需要參數列表中指定的請求名稱、數據速率和死區,速率和死區的實際值從服務器返回到相應的指針位置,組在創建時候總是激活(Active)狀態的。
RemoveOPCGroup(…)
??刪除并清除為定義的組分配的資源。
備注:數據速率指的是在數據訂閱模式下客戶端這個組里所有的項數據多久刷新一次,死區是當數據變化超過百分之多少的波動范圍時服務器會向客戶端這個組發出通知。組的句柄是在添加組的時候返回的,也要注意保存好。在移除組的時候,如果自己定義了相關的類或者結構體,記得把相關的變量自己清除。
譯文:

BOOL ChangeOPCGroupState(HANDLE hConnect, HANDLE hGroup, BOOL Active));

??使用此功能,可以激活(Active = TRUE)或停用(Active = FALSE)定義的OPC組。
頭文件注釋翻譯:
??允許應用激活和停用一個OPC組。
備注:這個功能沒用過,也不理解為什么要不激活- -。

譯文:

HANDLE AddOPCItem(HANDLE hConnect, HANDLE hGroup, LPCSTR ItemName); HANDLE AddOPCItemWithPath(HANDLE hConnect, HANDLE hGroup, LPCSTR PathName, LPCSTR ItemName); void RemoveOPCItem(HANDLE hConnect, HANDLE hGroup, HANDLE hItem);

??要將服務器標簽添加到定義的OPC組,只需使用組的句柄和所需添加項的服務器標簽名和/或路徑名調用AddOPCItem函數。這個函數將返回唯一的項句柄(如果請求的項不存在,比如服務器沒有這個名字的標簽,則返回無效的句柄值)。由于項都屬于某個組,關閉組時,需要調用RemoveOPCItem清除對每個項所分配的內存。
頭文件注釋翻譯:
AddOPCItem(…)
??請求連接的OPC服務器向指定組添加項目,返回值標識了訪問的項,用來在未來用戶應用程序通過這個返回值操作項,服務器沒有叫這個名字的項那么返回值為INVALID_HANDLE_VALUE。
AddOPCItemWithPath(…)
??與AddOPCItem相同,但允許用戶指定路徑。
RemoveOPCItem(…)
??移除指定的OPC項并且清空資源。
備注:同樣記得保存添加項時返回的項句柄。
譯文:

BOOL ChangeOPCItemState(HANDLE hConnect, HANDLE hGroup, HANDLE hItem, BOOL Active);

??使用此功能,可以激活(Active = TRUE)或停用(Active = FALSE)定義的OPC項。
頭文件注釋翻譯:
??允許應用激活和停用一個OPC項。
備注:同樣沒用過,可能有時候對某個項的數據不感興趣需要停用吧,不是很理解其用途。
譯文:

BOOL GetOPCItemNameFromHandle(HANDLE hConnect, HANDLE hGroup, HANDLE hItem,char *pBuf, int BufSize);

??此函數允許客戶端應用程序通過傳遞從AddOPCItem返回的句柄來檢索OPC項名稱,獲取到的標簽名會保存在char *pBuf,int BufSize是客戶端提供的標簽名最大長度。
頭文件注釋翻譯:
??允許用戶迭代從NumberOfOPCItems()獲取的項名稱列表。
備注:通過得到的項句柄來反向獲取服務器標簽的名字,有時候把每個項的句柄存了忘了存名字,用這個反向獲取名字,項的名字對于OPC客戶端來說在建立連接后其實就無所謂了,從之前的函數也可以看出來,項句柄才是最關鍵的,名字主要是各種界面顯示,需要給人看的。
譯文:

BOOL GetOPCItemType(HANDLE hConnect, HANDLE hGroup, LPCSTR ItemName,VARTYPE *pType, DWORD *pAccessRights);

??這個函數返回了指定標簽的VARTYPE *pType變量類型以及DWORD *pAccessRights讀寫權限。
頭文件注釋翻譯:
??允許應用程序獲取規范數據類型,以及給定項的讀/寫訪問屬性。返回值FALSE,表示請求的項名稱沒有存在于連接的服務器中。
備注:這個函數特殊一點,確實需要傳入項的名字,前三個參數分別是服務器句柄,組句柄和項名字,后面兩個數據類型和讀寫權限的參數只需要初始化即可,函數調用成功后會將獲取的數據類型和讀寫權限返回給這最后兩個參數的指針。
譯文:

int NumberOfItemProperties(HANDLE hConnect, LPCSTR ItemName);

??這個函數返回與指定標簽相關聯的 OPC 項屬性編號。
頭文件注釋翻譯:
??返回指定項的項屬性編號。使用GetItemPropertyDescription函數填充可訪問的屬性描述的內部數組。***小心***這是由dll為每個服務器維護的一個項屬性數組。應用程序必須讀取給定項的所有屬性描述,并在為新項調用NumberOfItemProperties之前保存PropertyID。
備注:在這兒特別區分一下,一般項和標簽都是混著說,但是準確的說,標簽指的是服務器中的一個數據點,一個項指的是客戶端到服務器一個具體標簽的連接,是的,項是一個抽象的東西,準確定義,它是一個“連接”。在DLL看來,服務器中每個標簽是按一個固定順序排列的,比如名字叫“123”的標簽在DLL看來就是服務器中第3個標簽,通過這個函數給定服務器中標簽名,可以查看當前標簽是服務器中第幾個標簽,這樣省去了用前面的函數一層一層遍歷來找指定標簽了。
譯文:

BOOL GetItemPropertyDescription(HANDLE hConnect, int PropertyIndex, DWORD *pPropertyID,VARTYPE *pVT, BYTE *pDescr, int BufSize);

??可以通過遍歷NumberOfOPCItemProperties創建的列表來獲得每個項屬性的BYTE *pDescr描述。
頭文件注釋翻譯:
??返回由NumberOfItemProperties()指定的最后一個項的屬性值說明,應用程序可以使用返回的PropertyID,并使用ReadPropertyValue()從服務器讀取屬性值。
備注:按照說明,這個函數用來獲取一個項屬性的描述,可能是對這個標簽的注釋吧,解釋這個標簽代表什么物理量,實際中暫時沒見過。

BOOL ReadPropertyValue(HANDLE hConnect, LPCSTR Itemname, DWORD PropertyID, VARIANT *pValue);

??ReadItemProperty返回項屬性的當前值。
頭文件注釋翻譯:
??ReadItemProperty返回項屬性的當前值。
備注:這里是把指定項的屬性值獲取到了,注意只是屬性值!比如這個項是什么數據類型,并不是項的值是多少!
譯文:
從OPC服務器獲取更新的標簽值(讀標簽值)

BOOL EnableOPCNotification(HANDLE hConnect, NOTIFYPROC lpCallback);

??如果應用程序支持回調,當連接的服務器發出了標簽數據值改變的通知時,WTclient將發出回調。回調的原型定義如下:

void CALLBACK EXPORT OPCUpdateCallback(HANDLE hGroup, HANDLE hItem, VARIANT *pVar, FILETIME timestamp, DWORD quality)

??一個標簽的當前值、時間戳和OPC質量標志將通過回調提供給應用程序。標簽由組句柄和項句柄聯系。
譯文:

BOOL ReadOPCItem(HANDLE hConnect, HANDLE hGroup, HANDLE hItem, VARIANT *pVar, FILETIME *pTimeStamp, DWORD *pQuality);

??如果已將WTclient配置為DLLBuffering=TRUE,由DLL維護項列表,則應用程序可通過ReadOPCItem函數讀取標簽的當前值。如果請求的項不可用(或DLLBuffering=FALSE),函數將返回FALSE
可由應用程序用于讀取項的當前值。
頭文件注釋翻譯:
??可由應用程序用于讀取項的當前值,僅當EnableDLLBuffering設置為TRUE時且已與服務器建立連接才有效。
備注:建立項后用來讀取對應標簽的值,包括其數值,數據類型,時間戳,點質量。
譯文:

HRESULT ReadOPCItemFromDevice(HANDLE hConnect, HANDLE hGroup, HANDLE hItem, VARIANT *pVar, FILETIME *pTimeStamp, DWORD *pQuality); HRESULT ReadOPCItemFromCache(HANDLE hConnect, HANDLE hGroup, HANDLE hItem, VARIANT *pVar, FILETIME *pTimeStamp, DWORD *pQuality);

??這些函數從連接的服務器對指定項執行同步的讀取。讀取數據可以從服務器的緩存請求,也可以直接從設備請求。
頭文件注釋翻譯:
ReadOPCItemFromDevice(…)
??使用SyncIO接口直接從服務器讀取一個OPC項。
ReadOPCItemFromCache(…)
??使用SyncIO接口直接從服務器緩存讀取一個OPC項。
備注:這兩個函數使用的是OPC同步IO接口,實現了同步讀,實際中用ReadOPCItem()一般就足夠了。
譯文:
向服務器寫標簽值

DWORD WriteOPCItem(HANDLE hConnect, HANDLE hGroup, HANDLE hItem, VARIANT *pVar, BOOL DoAsync);

??向連接的服務器寫入新數據是通過WriteOPCItem函數完成的。必須指定組和項的句柄以及要寫入的數據。DoAsync參數為TRUE時dll對服務器執行異步寫入。為FALSE則同步寫入,同步寫入時返回值表示從服務器返回的hResult,非零值表示錯誤。對于異步寫入,返回值是定義異步回調句柄的事務ID,零值表示錯誤。
頭文件注釋翻譯:
??允許控制應用程序寫入定義的OPC項,對于同步寫入,返回值為從服務器返回的hResult。對于異步寫入,返回值是一個非零的TransactionID,用于標識WriteCompletion回調。如果TransactionID返回零,則表示異步寫入請求失敗。
備注:同步寫類似一種阻塞方式,客戶端知道服務器全寫完了才能再寫,異步寫只需要發出寫的請求給服務器就可以了,服務器那邊寫完給不給客戶端通知完全不管,一般來說想追求效率肯定是異步寫較好。
譯文:

BOOL EnableAsyncWriteNotification(HANDLE hConnect, NOTIFYPROC lpCallback);

??對于異步寫入請求,可以將dll配置為在寫入完成時向應用程序發出回調。回調的原型定義如下:

void CALLBACK EXPORT AsyncWriteCallback (HANDLE hGroup, DWORD TransactionID, DWORD hResult)

??The TransactionID 定義特定于此回調的寫入請求,也就是說,之前的WriteOPCItem函數在異步寫時,如果返回的TransactionID與這里的回調中的TransactionID相等,那么進入這個回調。 hResult定義寫入狀態.,這個變量為S_OK,代表寫入成功,否則寫入失敗。
譯文:
一些雜項函數和回調函數

BOOL GetSvrStatus(HANDLE hConnect, OPCSERVERSTATUS *pSvrStatus,int VendorInforBufSize);

??在提供的緩沖區OPCSERVERSTATUS *pSvrStatus中返回標識的服務器的當前狀態。
頭文件注釋翻譯:
??允許控制應用程序詢問正在運行的連接的服務器的狀態。pSvrStatus指向包含指向要接收VendorInfo字符串(WSTR)的緩沖區的指針。VendorInfoBufSize定義此緩沖區的長度,以防止dll溢出??梢允褂胮SvrStatus=NULL調用GetSvrStatus,在這種情況下返回值TRUE表示服務器處理了接口調用,但是未返回任何數據。
備注:這個函數用來獲取服務器狀態。
譯文:

BOOL SetClientName(HANDLE hConnect, LPCSTR Name);

??此函數允許客戶端定義一個名稱來指定與服務器的連接。

BOOL EnableErrorNotification(ERRORPROCAPI lpCallback);

??WTClient dll可以通知客戶端應用程序在處理對OPC服務器的數據接口調用期間發生的錯誤。如果在處理用戶請求期間出現意外情況,則dll可能會生成錯誤消息。dll的默認操作是會彈出一個對話框提示用戶錯誤信息。在大多數情況下,應用程序本身更適合處理錯誤消息,而不是由dll生成對話框。如果啟用了EnableErrorNotification,則控件將通過以下回調傳遞給應用程序:

void CALLBACK EXPORT ErrorMsgCallback(DWORD hResult, char *pMsg)

??pMsg 中包含錯誤的文本描述以及由此產生的 hResult.

BOOL EnableClientEventMsgs(EVENTMSGPROC lpCallback);

??WTClient dll還可以在與服務器連接的操作過程中通知客戶端應用程序各種事件。這些事件基本上用于調試,并表示與處理單個接口相關的正?;顒?#xff08;例如進入和退出特定函數)。通常,客戶端應用程序不需要知道這些事件,但是,如果它希望提供連接如何工作的低級描述,則可以通過啟用事件msg在這些調試語句發生時接收它們。

void CALLBACK EXPORT EventMsgCallback(char *pMsg)

??pMsg包含事件的文本描述。

BOOL EnableShutdownNotification(HANDLE hConnect, SHUTDOWNPROCAPI lpCallback);

??如果連接的OPC服務器希望關閉,它可以請求任何或所有客戶端斷開連接。客戶端應用程序應在WTClient dll中啟用關閉通知EnableShutdownNotification來處理此請求并終止連接。

void CALLBACK EXPORT ShutdownCallback(HANDLE hConnect)

??hConnect參數標識請求斷開連接的服務器連接。

總結

以上是生活随笔為你收集整理的OPC通讯开发——客户端开发工具WTopcclient说明手册部分翻译及个人补充的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。