您现在所在的是:

PLC论坛

回帖:3个,阅读:1669 [上一页] [1] [下一页]
5356
shadowhao
文章数:1293
年度积分:50
历史总积分:5356
注册时间:2005/8/10
发站内信
发表于:2006/7/5 14:27:00
#0楼

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

研究了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;
}
4377
nyfuj 版主
文章数:1496
年度积分:50
历史总积分:4377
注册时间:2004/6/5
发站内信
发表于:2006/8/29 19:32:00
#1楼
收藏,顶
   时时勤拂拭,莫使染尘埃。没有六祖的顿悟,只求神秀的力学慎思。
                                                  心镜(nyfuj)
匿名用户
文章数:N/A
年度积分:0
历史总积分:0
注册时间:2006/10/23
发站内信
发表于:2006/10/23 13:48:00
#2楼
该用户被锁定,回复内容不予显示!
957
ziyuan_1016
文章数:3
年度积分:50
历史总积分:957
注册时间:2007/1/21
发站内信
发表于:2007/8/16 10:05:00
#3楼
这样的帖子越多越好啊
支持,收藏

关于我们 | 联系我们 | 广告服务 | 本站动态 | 友情链接 | 法律声明 | 非法和不良信息举报

工控网客服热线:0755-86369299
版权所有 工控网 Copyright©2025 Gkong.com, All Rights Reserved

124.8008