OPC Client 核心源码

来源:互联网 发布:淘宝免费全套模板下载 编辑:程序博客网 时间:2024/05/17 23:03

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

研究了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<dwCount;i++) phServer[i] = (OPCHANDLE)arrhServer.GetAt(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<dwCount;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<dwCount;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;
}

 

 

原创粉丝点击