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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

前言

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

一、手冊前言

備注:全文中如有“應(yīng)用程序”字樣,全部指的是“由開發(fā)者依據(jù)這個(gè)DLL開發(fā)的OPC客戶端應(yīng)用程序”

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

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

二、手冊正文部分函數(shù)翻譯和說明

譯文:
獲取 OPC 服務(wù)器列表
?? WTclient.dll 提供了兩個(gè)函數(shù)來使客戶端應(yīng)用程序可以獲取可用的OPC Servers列表.

int NumberOfOPCServers(BOOL UseOPCENUM, LPCSTR MachineName);

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

譯文:
?? 從WTclient.dll返回服務(wù)器數(shù)后,應(yīng)用程序可以通過調(diào)用下面函數(shù)獲取服務(wù)器名:

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

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

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

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

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

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

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

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

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

譯文:

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

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

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

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

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

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

譯文:

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

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

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

??使用此功能,可以激活(Active = TRUE)或停用(Active = FALSE)定義的OPC項(xiàng)。
頭文件注釋翻譯:
??允許應(yīng)用激活和停用一個(gè)OPC項(xiàng)。
備注:同樣沒用過,可能有時(shí)候?qū)δ硞€(gè)項(xiàng)的數(shù)據(jù)不感興趣需要停用吧,不是很理解其用途。
譯文:

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

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

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

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

int NumberOfItemProperties(HANDLE hConnect, LPCSTR ItemName);

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

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

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

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

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

BOOL EnableOPCNotification(HANDLE hConnect, NOTIFYPROC lpCallback);

??如果應(yīng)用程序支持回調(diào),當(dāng)連接的服務(wù)器發(fā)出了標(biāo)簽數(shù)據(jù)值改變的通知時(shí),WTclient將發(fā)出回調(diào)?;卣{(diào)的原型定義如下:

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

??一個(gè)標(biāo)簽的當(dāng)前值、時(shí)間戳和OPC質(zhì)量標(biāo)志將通過回調(diào)提供給應(yīng)用程序。標(biāo)簽由組句柄和項(xiàng)句柄聯(lián)系。
譯文:

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

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

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

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

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

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

BOOL EnableAsyncWriteNotification(HANDLE hConnect, NOTIFYPROC lpCallback);

??對于異步寫入請求,可以將dll配置為在寫入完成時(shí)向應(yīng)用程序發(fā)出回調(diào)。回調(diào)的原型定義如下:

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

??The TransactionID 定義特定于此回調(diào)的寫入請求,也就是說,之前的WriteOPCItem函數(shù)在異步寫時(shí),如果返回的TransactionID與這里的回調(diào)中的TransactionID相等,那么進(jìn)入這個(gè)回調(diào)。 hResult定義寫入狀態(tài).,這個(gè)變量為S_OK,代表寫入成功,否則寫入失敗。
譯文:
一些雜項(xiàng)函數(shù)和回調(diào)函數(shù)

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

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

BOOL SetClientName(HANDLE hConnect, LPCSTR Name);

??此函數(shù)允許客戶端定義一個(gè)名稱來指定與服務(wù)器的連接。

BOOL EnableErrorNotification(ERRORPROCAPI lpCallback);

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

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

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

BOOL EnableClientEventMsgs(EVENTMSGPROC lpCallback);

??WTClient dll還可以在與服務(wù)器連接的操作過程中通知客戶端應(yīng)用程序各種事件。這些事件基本上用于調(diào)試,并表示與處理單個(gè)接口相關(guān)的正常活動(例如進(jìn)入和退出特定函數(shù))。通常,客戶端應(yīng)用程序不需要知道這些事件,但是,如果它希望提供連接如何工作的低級描述,則可以通過啟用事件msg在這些調(diào)試語句發(fā)生時(shí)接收它們。

void CALLBACK EXPORT EventMsgCallback(char *pMsg)

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

BOOL EnableShutdownNotification(HANDLE hConnect, SHUTDOWNPROCAPI lpCallback);

??如果連接的OPC服務(wù)器希望關(guān)閉,它可以請求任何或所有客戶端斷開連接??蛻舳藨?yīng)用程序應(yīng)在WTClient dll中啟用關(guān)閉通知EnableShutdownNotification來處理此請求并終止連接。

void CALLBACK EXPORT ShutdownCallback(HANDLE hConnect)

??hConnect參數(shù)標(biāo)識請求斷開連接的服務(wù)器連接。

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。