OPC Client 核心源码

<meta content="MSHTML 6.00.2900.3199" name="GENERATOR"> <style></style>2005年12月02日 21:57:00

好像技术一沾上工业,便有了很高的价值,大家三缄其口,谁都不点破这层窗户纸,好多的思路和源码都要从国外网站获得,国内总是有条件,有限制--就是不告诉你,怕教会徒弟,饿死师父吧。

研究了N天,开发了一个基于我的组态后台的OPC客户端驱动,考虑到驱动的特殊性,所以只开发了同步接口操作。测试一段时间后,还可以。现把核心代码公开出来,有点VC基础的人可以直接拿来用。

//*************************************************************************
//函 数 名:ConnectOPC
//所属类名:COPCClien
//输 入:CString SvrName
//输 出:
//功能描述:连接OPC服务器
//全局变量:
//调用模块:
//作 者:叶帆
//日 期:2005年12月1日
//修 改 人:
//日 期:
//版 本:
//*************************************************************************
long COPCClient::ConnectOPC(CString cSvrName)
{
HRESULT hr;
CLSID clsid;
WCHAR wszProgID [512];

//----------------------------------
//初始化COM
hr =CoInitialize(NULL);
if (FAILED(hr)) return 8; //com初始化失败

//-----------------------------------
if(strSvrName!="") //判断是否已经连接OPC
{
if (strSvrName==cSvrName) return 2; //OPC服务器已经连接
else return 4; //只能连接一个OPC服务器
}
//-----------------------------------

try
{

//----------------------------------
//把字符串形式的对象标识转化为CLSID结构形式
_mbstowcsz (wszProgID, cSvrName, sizeof (wszProgID) / sizeof (WCHAR));
hr= CLSIDFromProgID(wszProgID, // [in]
&clsid); // [out]
if(FAILED(hr))
{
CoTaskMemFree(&clsid); //COM 内存释放函数
CoUninitialize(); //终止COM库功能服务
return 16; //获取clsid失败
}

//--------------------------------
//创建Server实例
hr=CoCreateInstance(clsid, //[in]
NULL, //[in]
CLSCTX_SERVER, //[in]
IID_IUnknown, //[in]
(void**)&pUNK); //[out]

if(FAILED(hr))
{
CoTaskMemFree(&clsid);
if(pUNK) pUNK-<release> pUNK=NULL;<br> CoUninitialize();<br> return 32; //创建Server实例失败<br> }<br><br> //------------------------------------<br> //查询pOPC接口<br> hr=pUNK-<queryinterface> (void**)&amp;pOPC);// [out]<br> if(FAILED(hr))<br> {<br> CoTaskMemFree(&amp;clsid);<br> if(pOPC) pOPC-<release> if(pUNK) pUNK-<release> pOPC=NULL;<br> pUNK=NULL;<br> return 64; //查询pOPC接口失败<br> }</release></release></queryinterface></release>

CoTaskMemFree(&clsid);

//---------------------------
strSvrName=cSvrName; //赋值当前OPC服务名称


}
catch(...)
{
return 128; //连接服务器时出现严重错误
}
return 0; //成功
}

//*************************************************************************
//函 数 名:DisconnectOPC
//所属类名:COPCClient
//输 入:
//输 出:long
//功能描述:断开OPC服务器
//全局变量:
//调用模块:
//作 者:叶帆
//日 期:2005年12月1日
//修 改 人:
//日 期:
//版 本:
//*************************************************************************
long COPCClient::DisconnectOPC()
{
if(strSvrName=="") return 1; //OPC服务器尚未连接

HRESULT *pErrors = NULL;
DWORD dwCount=mIOMDevice-<mitem.getsize><p> strSvrName=""; //服务器名称清空</p> <p> //---------------<br> OPCHANDLE *phServer = NULL;<br> //停止异步操作<br> pIAsync2-<setenable><br> //移除标签<br> phServer = (OPCHANDLE *) CoTaskMemAlloc (dwCount * sizeof (OPCHANDLE));<br> for(i=0;i&gt;dwCount;i++) phServer[i] = (OPCHANDLE)arrhServer.GetAt(i);</setenable></p> <p> pIItemMgt-<removeitems> phServer, // [in] <br> &amp;pErrors); // [out]</removeitems></p> <p> arrhServer.RemoveAll();<br> arrhServer.FreeExtra();<br> arrItemType.RemoveAll();<br> arrItemType.FreeExtra();<br><br> //删除组<br> pOPC-<removegroup> true); //[in]<br><br> //---------------<br> CoTaskMemFree(&amp;hServer);<br> CoTaskMemFree(&amp;hGroup);</removegroup></p> <p> if(pErrors) CoTaskMemFree(pErrors);<br> if(pResults) CoTaskMemFree(pResults);</p> <p> if(pIAsync2) pIAsync2-<release> if(pISync) pISync-<release> if(pIItemMgt) pIItemMgt-<release> if(pOPC) pOPC-<release> if(pUNK) pUNK-<release><p> pOPC=NULL;<br> pUNK=NULL;<br> pIItemMgt=NULL;<br> pIAsync2=NULL;<br> pISync=NULL;<br> hGroup=0;<br> hServer=0;<br><br> CoUninitialize(); //关闭COM</p> <p> return 0;<br>}</p> <p><br>//*************************************************************************<br>//函 数 名:AddGroup<br>//所属类名:COPCClient<br>//输 入:<br>//输 出:long<br>//功能描述:添加组<br>//全局变量:<br>//调用模块:<br>//作 者:叶帆<br>//日 期:2005年12月1日<br>//修 改 人:<br>//日 期:<br>//版 本:<br>//*************************************************************************<br>long COPCClient::AddGroup()<br>{<br> HRESULT hr;<br> WCHAR wchBuffer[255];<br> long lBias=0;<br> float fDeadband=0;<br> DWORD dwRevUpdateRate=0;<br> IUnknown *pUNKgroup; //组接口指针</p> <p> MultiByteToWideChar(CP_ACP, 0, mIOMDevice-<configmessage wchbuffer><br> //添加组<br> hr = pOPC-<addgroup> wchBuffer, // [in] group name<br> TRUE, // [in] active state<br> mIOMDevice-<scantime requested update rate> hGroup, // [in] our handle to this group<br> &amp;lBias, // [unique,in] time bias<br> &amp;fDeadband, // [in] percent deadband<br> 1033, // [in] requested language ID<br> &amp;hServer, // [out] server handle to this group<br> &amp;dwRevUpdateRate, // [out] revised update rate<br> IID_IUnknown, // [in] REFIID riid,<br> (LPUNKNOWN*)&amp;pUNKgroup); // [out, iid_is(riid)] LPUNKNOWN *pUNKgroup</scantime></addgroup></configmessage></p> <p> if(FAILED(hr)) //加入组失败<br> {<br> CoTaskMemFree(&amp;hServer);<br> CoTaskMemFree(&amp;dwRevUpdateRate);<br> if(pUNKgroup) pUNKgroup-<release> pUNKgroup=NULL;<br> return 1;<br> }</release></p> <p> //--------------------------------------<br> //查询pIItemMgt<br> hr=pUNKgroup-<queryinterface> (void**)&amp;pIItemMgt); // [out]</queryinterface></p> <p> //查询失败<br> if(FAILED(hr)) <br> {<br> CoTaskMemFree(&amp;hServer);<br> CoTaskMemFree(&amp;dwRevUpdateRate);<br> if(pUNKgroup) pUNKgroup-<release> pUNKgroup=NULL;<br> if(pIItemMgt) pIItemMgt-<release> pIItemMgt=NULL;<br> return 2; <br> }</release></release></p> <p> if(pUNKgroup) pUNKgroup-<release> pUNKgroup=NULL;<br> CoTaskMemFree(&amp;dwRevUpdateRate);<br> return 0;<br>}</release></p> <p>//*************************************************************************<br>//函 数 名:AddItem<br>//所属类名:COPCClient<br>//输 入:<br>//输 出:long<br>//功能描述:加入项<br>//全局变量:<br>//调用模块:<br>//作 者:叶帆<br>//日 期:2005年12月1日<br>//修 改 人:<br>//日 期:<br>//版 本:<br>//*************************************************************************<br>long COPCClient::AddItem()<br>{<br> HRESULT hr;<br> OPCITEMDEF *pItemArray = NULL;</p> <p> HRESULT *pErrors = NULL;<br> DWORD dwCount,dwLen,i;<br><br> //--------------------------------------<br> //添加标签<br> dwCount=mIOMDevice-<mitem.getsize> pItemArray = (OPCITEMDEF *) CoTaskMemAlloc (dwCount * sizeof (OPCITEMDEF)); //分配内存<br><br> for(i=0;i&gt;dwCount;i++)<br> {<br> dwLen = lstrlen (mIOMDevice-<mitem> pItemArray [i].szItemID = (WCHAR *) CoTaskMemAlloc ((dwLen + 1) * sizeof (WCHAR));<br> MultiByteToWideChar (CP_ACP, 0, mIOMDevice-<mitem pitemarray dwlen> pItemArray [i].szAccessPath=NULL;<br> pItemArray [i].bActive = true; // active state<br> pItemArray [i].hClient = (OPCHANDLE)i; // our handle to item<br> pItemArray [i].dwBlobSize = 0; // no blob support<br> pItemArray [i].pBlob = NULL;<br> pItemArray [i].vtRequestedDataType =VT_EMPTY; // Requested data type<br> pItemArray [i].wReserved=0;<br> }<br><br> //添加<br> hr = pIItemMgt-<additems dword dwcount count> pItemArray, //[in, size_is(dwCount)] OPCITEMDEF * pItemArray, Array of item definition structures<br> &amp;pResults, //[out, size_is(,dwCount)] OPCITEMRESULT ** ppAddResults, Result array<br> &amp;pErrors); //[out, size_is(,dwCount)] HRESULT ** ppErrors Error array<br> //添加失败<br> if(FAILED(hr))<br> {<br> if(pResults) CoTaskMemFree(pResults);<br> if(pErrors) CoTaskMemFree(pErrors);<br> CoTaskMemFree(&amp;hServer);<br> CoTaskMemFree(pItemArray);<br> return 2;<br> }<br><br> //同步接口<br> hr=pIItemMgt-<queryinterface> (void**)&amp;pISync); // [out]</queryinterface></additems></mitem></mitem></mitem.getsize></p> <p> if(FAILED (hr))<br> {<br> CoTaskMemFree(&amp;hServer);<br> if(pISync) pISync-<release> if(pResults) CoTaskMemFree(pResults);<br> if(pErrors) CoTaskMemFree(pErrors);<br> pISync=NULL;<br> return 3; //查询pISync接口失败<br> }<br><br> //异步接口<br> hr=pIItemMgt-<queryinterface> if(FAILED (hr))<br> {<br> CoTaskMemFree(&amp;hServer);<br> if(pIAsync2) pIAsync2-<release> if(pResults) CoTaskMemFree(pResults);<br> if(pErrors) CoTaskMemFree(pErrors);<br> pIAsync2=NULL;<br> return 4; //查询pIAsync2接口失败<br> }<br><br> //---------------------<br> arrhServer.SetSize(dwCount);<br> arrItemType.SetSize(dwCount);</release></queryinterface></release></p> <p> for(i=0;i&gt;dwCount;i++)<br> {<br> arrhServer.SetAt(i,pResults[i].hServer );<br> arrItemType.SetAt(i,(WORD)pResults[i].vtCanonicalDataType);<br> }</p> <p> //---------------------</p> <p> if(pErrors) CoTaskMemFree(pErrors);<br> CoTaskMemFree(pItemArray);<br> return 0;<br>}</p> <p>//*************************************************************************<br>//函 数 名:SyncRead<br>//所属类名:COPCClient<br>//输 入:long lngNo,<br>// CString strData<br>//输 出:long<br>//功能描述:同步读取数据<br>//全局变量:<br>//调用模块:<br>//作 者:叶帆<br>//日 期:2005年12月1日<br>//修 改 人:<br>//日 期:<br>//版 本:<br>//*************************************************************************<br>long COPCClient::SyncRead(long lngNo,CString &amp;strData)<br>{<br> HRESULT hr = E_FAIL;<br> DWORD dwCount=1;<br> OPCDATASOURCE dwSource = OPC_DS_CACHE;<br> OPCHANDLE *phServer = NULL;<br> OPCITEMSTATE *pValues = NULL;<br> HRESULT *pErrors = NULL;</p> <p> ::Sleep(0);</p> <p> try<br> {<br> phServer = (OPCHANDLE *) CoTaskMemAlloc (dwCount * sizeof (OPCHANDLE));<br> if (phServer == NULL)<br> {<br> return 1; //分配内存时出错<br> }</p> <p> phServer[0] =(OPCHANDLE)arrhServer.GetAt(lngNo);<br> hr=pISync-<read> dwCount, //[in]<br> phServer, //[in]<br> &amp;pValues, //[out]<br> &amp;pErrors); //[out]<br> if(FAILED(hr))<br> {<br> if (phServer) CoTaskMemFree (phServer);<br> if (pValues) CoTaskMemFree (pValues); <br> if (pErrors) CoTaskMemFree (pErrors);<br> VariantClear (&amp;pValues[0].vDataValue);<br> return 2; //同步读数据时出错<br> }</read></p> <p> //数据转换<br> Variant2Str(pValues[0].vDataValue,strData);<br> VariantClear (&amp;pValues[0].vDataValue);</p> <p> if (phServer) CoTaskMemFree (phServer);<br> if (pValues) CoTaskMemFree (pValues); <br> if (pErrors) CoTaskMemFree (pErrors);<br> }<br> catch (...)<br> {<br> return 3;<br> }</p> <p> return 0;<br>}</p> <p>//*************************************************************************<br>//函 数 名:SyncWrite<br>//所属类名:COPCClient<br>//输 入:long lngNo,<br>// CString &amp;strData<br>//输 出:long<br>//功能描述:同步写<br>//全局变量:<br>//调用模块:<br>//作 者:叶帆<br>//日 期:2005年12月1日<br>//修 改 人:<br>//日 期:<br>//版 本:<br>//*************************************************************************<br>long COPCClient::SyncWrite(long lngNo,CString strData)<br>{ </p> <p> DWORD dwIndex = 0;<br> OPCHANDLE *phServer = NULL;<br> VARIANT *pValues = NULL;<br> HRESULT *pErrors = NULL;<br> HRESULT hr = E_FAIL;<br> DWORD cdwItems=1;</p> <p> phServer = (OPCHANDLE *) CoTaskMemAlloc (cdwItems * sizeof (OPCHANDLE));<br> pValues = (VARIANT *) CoTaskMemAlloc (cdwItems * sizeof (VARIANT));</p> <p> if (phServer == NULL || pValues == NULL)<br> {<br> return 1;<br> }<br><br> ::Sleep(0);<br><br> try<br> {<br> //同步写数据<br> phServer[0] =(OPCHANDLE)arrhServer.GetAt(lngNo);<br><br> //数据转换 <br> Str2Variant(strData,pValues[0],arrItemType.GetAt(lngNo));</p> <p> hr = pISync-<write> 1, // Item count<br> phServer, // Array of server handles for items<br> pValues, // Array of values<br> &amp;pErrors); // Array of errors</write></p> <p> if(FAILED(hr))<br> {<br> if (phServer) CoTaskMemFree (phServer);<br> if (pValues) CoTaskMemFree (pValues); <br> if (pErrors) CoTaskMemFree (pErrors);<br> VariantClear (&amp;pValues[0]);<br> return 2; //同步读数据时出错<br> }<br><br> VariantClear (&amp;pValues[0]);<br> }<br><br> catch (...)<br> {<br> return 3;<br> }</p> <p> if(phServer)CoTaskMemFree (phServer);<br> if (pValues)CoTaskMemFree (pValues);<br> if (pErrors) CoTaskMemFree (pErrors);<br><br> return 0;<br>}</p> <p></p> <p></p> <br><br><p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=542447</p> <br></release></release></release></release></release></p></mitem.getsize>

你可能感兴趣的:(数据结构,cache,Blog,vc++)