首页 上一页 1 2 下一页 尾页

OPC Client 核心源码(MFC) 点击:10516 | 回复:38



叶帆

    
  • 精华:1帖
  • 求助:0帖
  • 帖子:18帖 | 88回
  • 年度积分:0
  • 历史总积分:239
  • 注册:2003年9月03日
发表于:2005-12-02 22:01:00
楼主
好像技术一沾上工业,便有了很高的价值,大家三缄其口,谁都不点破这层窗户纸,好多的思路和源码都要从国外网站获得,国内总是有条件,有限制--就是不告诉你,怕教会徒弟,饿死师父吧。

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

源码网址:http://blog.csdn.net/yefanqiu/archive/2005/12/02/542447.aspx



叶帆

  • 精华:1帖
  • 求助:0帖
  • 帖子:18帖 | 88回
  • 年度积分:0
  • 历史总积分:239
  • 注册:2003年9月03日
发表于:2005-12-02 23:15:00
1楼
//*************************************************************************
//函 数 名: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;
}

叶帆

  • 精华:1帖
  • 求助:0帖
  • 帖子:18帖 | 88回
  • 年度积分:0
  • 历史总积分:239
  • 注册:2003年9月03日
发表于:2005-12-02 23:17:00
2楼
毕竟是接触OPC不长时间做得,有可能有问题,望方家不吝指正

御风而行

  • 精华:1帖
  • 求助:0帖
  • 帖子:13帖 | 88回
  • 年度积分:0
  • 历史总积分:199
  • 注册:2002年11月12日
发表于:2005-12-06 16:39:00
3楼
感谢你的分享,我看过你的博客,在这方面应该是我的老师,学学你的程序吧,有问题向你请教

叶帆

  • 精华:1帖
  • 求助:0帖
  • 帖子:18帖 | 88回
  • 年度积分:0
  • 历史总积分:239
  • 注册:2003年9月03日
发表于:2005-12-06 21:37:00
4楼
不客气,彼此学习

蓝色可乐

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 6回
  • 年度积分:0
  • 历史总积分:51
  • 注册:2003年8月07日
发表于:2005-12-12 12:43:00
5楼
 “ 好像技术一沾上工业,便有了很高的价值,大家三缄其口,谁都不点破这层窗户纸,好多的思路和源码都要从国外网站获得,国内总是有条件,有限制--就是不告诉你,怕教会徒弟,饿死师父吧。”

你说的太对了!!!!我现在就是在艰苦的学习阶段,好在有网络,还有你们这些人!谢了!

浪费青春

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 95回
  • 年度积分:0
  • 历史总积分:124
  • 注册:2004年6月01日
发表于:2005-12-15 13:38:00
6楼
谢谢叶帆

OPC高手

  • 精华:0帖
  • 求助:0帖
  • 帖子:4帖 | 15回
  • 年度积分:0
  • 历史总积分:219
  • 注册:2003年10月16日
发表于:2005-12-16 08:33:00
7楼
你为什么不到www.opc-china.com看看,也许对你进步更快!

叶帆

  • 精华:1帖
  • 求助:0帖
  • 帖子:18帖 | 88回
  • 年度积分:0
  • 历史总积分:239
  • 注册:2003年9月03日
发表于:2005-12-16 14:02:00
8楼
正在研究,做出来后,一定公布相关代码

乐乐一天

  • 精华:0帖
  • 求助:0帖
  • 帖子:7帖 | 20回
  • 年度积分:0
  • 历史总积分:41
  • 注册:2006年4月28日
发表于:2006-05-15 14:23:00
9楼
感谢你的代码?虽然我目前用不上,但是我很敬佩你大无为精神,我也是初学者,我会想你学习的。

叶帆

  • 精华:1帖
  • 求助:0帖
  • 帖子:18帖 | 88回
  • 年度积分:0
  • 历史总积分:239
  • 注册:2003年9月03日
发表于:2006-05-26 20:44:00
10楼
OPC Server与IO Server的成功绑定。
http://blog.csdn.net/yefanqiu/archive/2006/05/02/705356.aspx

很可惜,OPC Server的源码是公司购买的,所以就不方便公开源码了,不过可以进行技术交流。

蓝色草原

  • 精华:0帖
  • 求助:0帖
  • 帖子:9帖 | 31回
  • 年度积分:0
  • 历史总积分:73
  • 注册:2003年10月23日
发表于:2006-05-27 19:52:00
11楼
感谢你的代码,如果大家都公开自己的技术,我们会进步的更快.一定会超过国外.不能总是跟在外国人的后面走.

不死小强

  • 精华:0帖
  • 求助:0帖
  • 帖子:15帖 | 57回
  • 年度积分:0
  • 历史总积分:129
  • 注册:2007年4月03日
发表于:2007-09-19 11:30:00
12楼
mark~

dotnew

  • 精华:0帖
  • 求助:0帖
  • 帖子:16帖 | 185回
  • 年度积分:0
  • 历史总积分:447
  • 注册:2007年3月08日
发表于:2007-09-20 09:40:00
13楼
支持叶舤

蓝光芒

  • 精华:0帖
  • 求助:2帖
  • 帖子:11帖 | 122回
  • 年度积分:0
  • 历史总积分:431
  • 注册:2006年9月25日
发表于:2007-12-24 20:11:00
14楼
开源必定是未来的趋势,导致这个趋势的不是商业的物质利益,而是精神。

国产组态

  • 精华:0帖
  • 求助:0帖
  • 帖子:7帖 | 129回
  • 年度积分:0
  • 历史总积分:706
  • 注册:2006年4月05日
发表于:2007-12-25 09:02:00
15楼
支持开源

AB菜鸟

  • 精华:0帖
  • 求助:0帖
  • 帖子:14帖 | 228回
  • 年度积分:0
  • 历史总积分:361
  • 注册:2003年10月26日
发表于:2007-12-25 11:28:00
16楼
顶起来

LUGANCHAO

  • 精华:0帖
  • 求助:0帖
  • 帖子:10帖 | 1821回
  • 年度积分:0
  • 历史总积分:2757
  • 注册:2007年4月06日
发表于:2007-12-25 14:37:00
17楼
  顶起来

LUGANCHAO

  • 精华:0帖
  • 求助:0帖
  • 帖子:10帖 | 1821回
  • 年度积分:0
  • 历史总积分:2757
  • 注册:2007年4月06日
发表于:2007-12-25 14:37:00
18楼
  顶起来

LUGANCHAO

  • 精华:0帖
  • 求助:0帖
  • 帖子:10帖 | 1821回
  • 年度积分:0
  • 历史总积分:2757
  • 注册:2007年4月06日
发表于:2007-12-25 14:37:00
19楼
  顶起来

LUGANCHAO

  • 精华:0帖
  • 求助:0帖
  • 帖子:10帖 | 1821回
  • 年度积分:0
  • 历史总积分:2757
  • 注册:2007年4月06日
发表于:2007-12-25 14:37:00
20楼
  顶起来

热门招聘
相关主题

官方公众号

智造工程师
    首页 上一页 1 2 下一页 尾页