OPC Client 核心源码

本文介绍了基于组态后台的OPC客户端驱动开发过程,并提供了核心代码。文章详细讲解了连接、断开OPC服务器,以及添加组和项等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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- pUNK=NULL;
CoUninitialize();
return 32; //创建Server实例失败
}

//------------------------------------
//查询pOPC接口
hr=pUNK- (void**)&pOPC);// [out]
if(FAILED(hr))
{
CoTaskMemFree(&clsid);
if(pOPC) pOPC- if(pUNK) pUNK- 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-

strSvrName=""; //服务器名称清空

//---------------
OPCHANDLE *phServer = NULL;
//停止异步操作
pIAsync2-
//移除标签
phServer = (OPCHANDLE *) CoTaskMemAlloc (dwCount * sizeof (OPCHANDLE));
for(i=0;i>dwCount;i++) phServer[i] = (OPCHANDLE)arrhServer.GetAt(i);

pIItemMgt- phServer, // [in]
&pErrors); // [out]

arrhServer.RemoveAll();
arrhServer.FreeExtra();
arrItemType.RemoveAll();
arrItemType.FreeExtra();

//删除组
pOPC- true); //[in]

//---------------
CoTaskMemFree(&hServer);
CoTaskMemFree(&hGroup);

if(pErrors) CoTaskMemFree(pErrors);
if(pResults) CoTaskMemFree(pResults);

if(pIAsync2) pIAsync2- if(pISync) pISync- if(pIItemMgt) pIItemMgt- if(pOPC) pOPC- if(pUNK) pUNK-

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-
//添加组
hr = pOPC- wchBuffer, // [in] group name
TRUE, // [in] active state
mIOMDevice- 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- pUNKgroup=NULL;
return 1;
}

//--------------------------------------
//查询pIItemMgt
hr=pUNKgroup- (void**)&pIItemMgt); // [out]

//查询失败
if(FAILED(hr))
{
CoTaskMemFree(&hServer);
CoTaskMemFree(&dwRevUpdateRate);
if(pUNKgroup) pUNKgroup- pUNKgroup=NULL;
if(pIItemMgt) pIItemMgt- pIItemMgt=NULL;
return 2;
}

if(pUNKgroup) pUNKgroup- 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- pItemArray = (OPCITEMDEF *) CoTaskMemAlloc (dwCount * sizeof (OPCITEMDEF)); //分配内存

for(i=0;i>dwCount;i++)
{
dwLen = lstrlen (mIOMDevice- pItemArray [i].szItemID = (WCHAR *) CoTaskMemAlloc ((dwLen + 1) * sizeof (WCHAR));
MultiByteToWideChar (CP_ACP, 0, mIOMDevice- 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- 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- (void**)&pISync); // [out]

if(FAILED (hr))
{
CoTaskMemFree(&hServer);
if(pISync) pISync- if(pResults) CoTaskMemFree(pResults);
if(pErrors) CoTaskMemFree(pErrors);
pISync=NULL;
return 3; //查询pISync接口失败
}

//异步接口
hr=pIItemMgt- if(FAILED (hr))
{
CoTaskMemFree(&hServer);
if(pIAsync2) pIAsync2- 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- 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- 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;
}



Trackback: http://tb.blog.youkuaiyun.com/TrackBack.aspx?PostId=542447


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值