登录
首页 PLC论坛 PLC论坛
回帖 发帖
正文

主题:OPC Client 核心源码[转帖]

点击:1812 回复:3


好像技术一沾上工业,便有了很高的价值,大家三缄其口,谁都不点破这层窗户纸,好多的思路和源码都要从国外网站获得,国内总是有条件,有限制--就是不告诉你,怕教会徒弟,饿死师父吧。
研究了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;
  CoUninitialize();
  return 32;                   //创建Server实例失败
 }

 //------------------------------------
 //查询pOPC接口
 hr=pUNK->QueryInterface(IID_IOPCServer,// [in]
       (void**)&pOPC);// [out]
 if(FAILED(hr))
 {
  CoTaskMemFree(&clsid);
  if(pOPC) pOPC->Release();
  if(pUNK) pUNK->Release();
  pOPC=NULL;
  pUNK=NULL;
  return 64;                   //查询pOPC接口失败
 }
 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(),i;
strSvrName="";                  //服务器名称清空
//---------------
OPCHANDLE *phServer = NULL;
//停止异步操作
pIAsync2->SetEnable(false);
           
//移除标签
phServer = (OPCHANDLE *) CoTaskMemAlloc (dwCount * sizeof (OPCHANDLE));
for(i=0;i pIItemMgt->RemoveItems(dwCount,   // [in]
        phServer,   // [in]
       &pErrors);  // [out]
arrhServer.RemoveAll();
arrhServer.FreeExtra();
arrItemType.RemoveAll();
arrItemType.FreeExtra();

//删除组
pOPC->RemoveGroup(hServer,   //[in]
     true);      //[in]
 
//---------------
CoTaskMemFree(&hServer);
CoTaskMemFree(&hGroup);
if(pErrors) CoTaskMemFree(pErrors);
   if(pResults) CoTaskMemFree(pResults);
if(pIAsync2) pIAsync2->Release();
if(pISync) pISync->Release();
if(pIItemMgt) pIItemMgt->Release();
if(pOPC) pOPC->Release();
if(pUNK) pUNK->Release();
pOPC=NULL;
pUNK=NULL;
pIItemMgt=NULL;
pIAsync2=NULL;
pISync=NULL;
hGroup=0;
hServer=0;

CoUninitialize();                //关闭COM
return 0;
}
//*************************************************************************
//函 数 名:AddGroup
//所属类名:COPCClient
//输    入:
//输    出:long
//功能描述:添加组
//全局变量:
//调用模块:
//作    者:叶帆
//日    期:2005年12月1日
//修 改 人:
//日    期:
//版    本:
//*************************************************************************
long COPCClient::AddGroup()
{
HRESULT hr;
   WCHAR wchBuffer[255];
long lBias=0;
float fDeadband=0;
DWORD dwRevUpdateRate=0;
IUnknown *pUNKgroup;        //组接口指针
MultiByteToWideChar(CP_ACP, 0, mIOMDevice->ConfigMessage, -1, wchBuffer, 255);
   
//添加组
hr = pOPC->AddGroup (
  wchBuffer,     // [in] group name
  TRUE,                  // [in] active state
  mIOMDevice->Scantime,       // [in] requested update rate
  hGroup,                  // [in] our handle to this group
  &lBias,      // [unique,in] time bias
  &fDeadband,     // [in] percent deadband
  1033,                     // [in] requested language ID
  &hServer,     // [out] server handle to this group
  &dwRevUpdateRate,   // [out] revised update rate
  IID_IUnknown,               // [in] REFIID riid,
  (LPUNKNOWN*)&pUNKgroup);    // [out, iid_is(riid)] LPUNKNOWN *pUNKgroup
if(FAILED(hr))  //加入组失败
{
 CoTaskMemFree(&hServer);
 CoTaskMemFree(&dwRevUpdateRate);
 if(pUNKgroup) pUNKgroup->Release();
 pUNKgroup=NULL;
 return 1;
}
//--------------------------------------
//查询pIItemMgt
hr=pUNKgroup->QueryInterface(IID_IOPCItemMgt,     // [in]
       (void**)&pIItemMgt);  // [out]
   //查询失败
   if(FAILED(hr))
{
 CoTaskMemFree(&hServer);
 CoTaskMemFree(&dwRevUpdateRate);
 if(pUNKgroup) pUNKgroup->Release();
 pUNKgroup=NULL;
 if(pIItemMgt) pIItemMgt->Release();
 pIItemMgt=NULL;
 return 2;  
}
if(pUNKgroup) pUNKgroup->Release();
   pUNKgroup=NULL;
CoTaskMemFree(&dwRevUpdateRate);
   return 0;
}
//*************************************************************************
//函 数 名:AddItem
//所属类名:COPCClient
//输    入:
//输    出:long
//功能描述:加入项
//全局变量:
//调用模块:
//作    者:叶帆
//日    期:2005年12月1日
//修 改 人:
//日    期:
//版    本:
//*************************************************************************
long COPCClient::AddItem()
{
HRESULT hr;
OPCITEMDEF *pItemArray = NULL;
HRESULT *pErrors = NULL;
DWORD dwCount,dwLen,i;
   
   //--------------------------------------
   //添加标签
   dwCount=mIOMDevice->mItem.GetSize();
 pItemArray = (OPCITEMDEF *) CoTaskMemAlloc (dwCount * sizeof (OPCITEMDEF)); //分配内存
 
for(i=0;i {
 dwLen = lstrlen (mIOMDevice->mItem[i].strTab);
 pItemArray [i].szItemID = (WCHAR *) CoTaskMemAlloc ((dwLen + 1) * sizeof (WCHAR));
 MultiByteToWideChar (CP_ACP, 0, mIOMDevice->mItem[i].strTab, -1, pItemArray [i].szItemID, dwLen + 1);
 pItemArray [i].szAccessPath=NULL;
 pItemArray [i].bActive = true;                     // active state
 pItemArray [i].hClient = (OPCHANDLE)i;             // our handle to item
 pItemArray [i].dwBlobSize = 0;            // no blob support
 pItemArray [i].pBlob = NULL;
 pItemArray [i].vtRequestedDataType =VT_EMPTY;       // Requested data type
 pItemArray [i].wReserved=0;
}
   
   //添加
hr = pIItemMgt->AddItems (dwCount,   //[in] DWORD dwCount,Item count
      pItemArray,  //[in, size_is(dwCount)] OPCITEMDEF * pItemArray, Array of item definition structures
      &pResults,   //[out, size_is(,dwCount)] OPCITEMRESULT ** ppAddResults, Result array
      &pErrors);   //[out, size_is(,dwCount)] HRESULT ** ppErrors Error array
//添加失败
if(FAILED(hr))
{
    if(pResults) CoTaskMemFree(pResults);
 if(pErrors) CoTaskMemFree(pErrors);
 CoTaskMemFree(&hServer);
 CoTaskMemFree(pItemArray);
       return 2;
}
   
//同步接口
hr=pIItemMgt->QueryInterface(IID_IOPCSyncIO,  // [in]
       (void**)&pISync); // [out]
if(FAILED (hr))
{
 CoTaskMemFree(&hServer);
 if(pISync) pISync->Release();
 if(pResults) CoTaskMemFree(pResults);
       if(pErrors) CoTaskMemFree(pErrors);
 pISync=NULL;
 return 3;          //查询pISync接口失败
}
   
//异步接口
hr=pIItemMgt->QueryInterface(IID_IOPCAsyncIO2,(void**)&pIAsync2);
if(FAILED (hr))
{
 CoTaskMemFree(&hServer);
 if(pIAsync2) pIAsync2->Release();
 if(pResults) CoTaskMemFree(pResults);
       if(pErrors) CoTaskMemFree(pErrors);
 pIAsync2=NULL;
 return 4;         //查询pIAsync2接口失败
}
   
//---------------------
arrhServer.SetSize(dwCount);
arrItemType.SetSize(dwCount);
for(i=0;i {
 arrhServer.SetAt(i,pResults[i].hServer );
 arrItemType.SetAt(i,(WORD)pResults[i].vtCanonicalDataType);
}
//---------------------
   if(pErrors) CoTaskMemFree(pErrors);
CoTaskMemFree(pItemArray);
   return 0;
}
//*************************************************************************
//函 数 名:SyncRead
//所属类名:COPCClient
//输    入:long lngNo,
//   CString strData
//输    出:long
//功能描述:同步读取数据
//全局变量:
//调用模块:
//作    者:叶帆
//日    期:2005年12月1日
//修 改 人:
//日    期:
//版    本:
//*************************************************************************
long COPCClient::SyncRead(long lngNo,CString &strData)
{
   HRESULT hr = E_FAIL;
DWORD dwCount=1;
OPCDATASOURCE dwSource = OPC_DS_CACHE;
OPCHANDLE *phServer  = NULL;
OPCITEMSTATE *pValues = NULL;
HRESULT *pErrors  = NULL;
::Sleep(0);
try
{
 phServer = (OPCHANDLE *) CoTaskMemAlloc (dwCount * sizeof (OPCHANDLE));
 if (phServer == NULL)
 {
  return 1;   //分配内存时出错
 }
 phServer[0] =(OPCHANDLE)arrhServer.GetAt(lngNo);
 hr=pISync->Read(dwSource,   //[in]
     dwCount,    //[in]
     phServer,   //[in]
     &pValues,   //[out]
     &pErrors);  //[out]
 if(FAILED(hr))
 {
  if (phServer) CoTaskMemFree (phServer);
     if (pValues) CoTaskMemFree (pValues);
     if (pErrors) CoTaskMemFree (pErrors);
  VariantClear (&pValues[0].vDataValue);
  return 2;   //同步读数据时出错
 }
 //数据转换
 Variant2Str(pValues[0].vDataValue,strData);
 VariantClear (&pValues[0].vDataValue);
 if (phServer) CoTaskMemFree (phServer);
 if (pValues) CoTaskMemFree (pValues);
 if (pErrors) CoTaskMemFree (pErrors);
}
   catch (...)
{
    return 3;
}
return 0;
}
//*************************************************************************
//函 数 名:SyncWrite
//所属类名:COPCClient
//输    入:long lngNo,
//   CString &strData
//输    出:long
//功能描述:同步写
//全局变量:
//调用模块:
//作    者:叶帆
//日    期:2005年12月1日
//修 改 人:
//日    期:
//版    本:
//*************************************************************************
long COPCClient::SyncWrite(long lngNo,CString strData)
{  
DWORD dwIndex  = 0;
OPCHANDLE *phServer = NULL;
VARIANT *pValues = NULL;
HRESULT *pErrors = NULL;
HRESULT hr   = E_FAIL;
DWORD cdwItems=1;
phServer = (OPCHANDLE *) CoTaskMemAlloc (cdwItems * sizeof (OPCHANDLE));
pValues = (VARIANT *) CoTaskMemAlloc (cdwItems * sizeof (VARIANT));
if (phServer == NULL || pValues == NULL)
{
   return 1;
}
   
::Sleep(0);

try
{
       //同步写数据
 phServer[0] =(OPCHANDLE)arrhServer.GetAt(lngNo);
       
 //数据转换
 Str2Variant(strData,pValues[0],arrItemType.GetAt(lngNo));
 hr = pISync->Write (
   1,             // Item count
   phServer,  // Array of server handles for items
   pValues,  // Array of values
   &pErrors);  // Array of errors
 if(FAILED(hr))
 {
  if (phServer) CoTaskMemFree (phServer);
     if (pValues) CoTaskMemFree (pValues);
     if (pErrors) CoTaskMemFree (pErrors);
  VariantClear (&pValues[0]);
  return 2;   //同步读数据时出错
 }

 VariantClear (&pValues[0]);
}

catch (...)
{
    return 3;
}
if(phServer)CoTaskMemFree (phServer);
if (pValues)CoTaskMemFree (pValues);
if (pErrors) CoTaskMemFree (pErrors);
   
return 0;
}
06-07-05 14:27
收藏,顶
06-08-29 19:32
2楼
该帖内容不符合相关规定!
06-10-23 13:48
这样的帖子越多越好啊
支持,收藏
07-08-16 10:05

工控新闻

更多新闻资讯