好像技术一沾上工业,便有了很高的价值,大家三缄其口,谁都不点破这层窗户纸,好多的思路和源码都要从国外网站获得,国内总是有条件,有限制--就是不告诉你,怕教会徒弟,饿死师父吧。
研究了N天,开发了一个基于我的组态后台的OPC客户端驱动,考虑到驱动的特殊性,所以只开发了同步接口操作。测试一段时间后,还可以。现把核心代码公开出来,有点VC基础的人可以直接拿来用。
//*************************************************************************
//函 数 名:ConnectOPC
//所属类名:COPCClien
//输 入:CString SvrName
//输 出:
//功能描述:连接OPC服务器
//全局变量:
//调用模块:
//作 者:叶帆
//日 期:2005年12月1日
//修 改 人:
//日 期:
//版 本:
//*************************************************************************
long COPCClient::ConnectOPC(CString cSvrName)
{
HRESULT hr;
CLSIDclsid;
WCHARwszProgID [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;
WCHARwchBuffer[255];
longlBias=0;
floatfDeadband=0;
DWORDdwRevUpdateRate=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)
{
HRESULThr = 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;
}
分享到:
相关推荐
资源名:Visual C++ OPC Client程序源码.zip 资源类型:程序源代码 源码说明: 基于Visual C++写的OPC Client客户端程序实例源码 包含完整代码和注释 很适合借鉴学习 适合人群:新手及有一定经验的开发人员
【程序老媛出品,必属精品,亲测校正,质量...资源名:基于java开发的opc client程序源码.zip 资源类型:程序源代码 源码说明: java实现的opc client,带有丰富接口和说明文档 适合人群:新手及有一定经验的开发人员
OPC Quick Client源码是一个基于此标准的客户端实现,它提供了快速访问OPC服务器数据的能力。这个源码是用Visual Studio 2008开发的,所以我们可以期待它是使用C++或C#语言编写的,并且兼容.NET Framework 3.5。 在...
在本资源中,我们拥有的是一个OPC Client的源码,这个客户端程序能够同时连接到多个本地或远程的OPC Server,从而实现高效的数据交互。 OPC Client是OPC技术中的客户端部分,它负责从OPC Server获取数据或者向OPC ...
【程序老媛出品,必属精品,亲测校正,质量保证】 ...源码说明: c#写的OPC Client源码 OPC同步读写程序,支持访问OPCServer数据,同步写数据,同步读数据。 适合人群:新手及有一定经验的开发人员
在本项目中,我们关注的是OPC客户端的源码开发,特别是使用C#语言开发的版本。 该项目的主要特点和应用领域如下: 1. 项目开发环境为Visual Studio 2019,具有良好的兼容性,支持多个版本的Visual Studio编辑器,...
高质量的OPCClient_UA源码分享:基于C#的OPC客户端开发源码集(测试稳定、多行业应用实例、VS编辑器支持),高质量OPC客户端源码解析:OPCClient_UA C#开发,适用于VS2019及多行业现场应用源码分享,OPCClient_UA源码...
"opc client 源码"这部分资源对于初学者非常有价值,因为它提供了一个实际的、可运行的示例,你可以直接在Visual Studio(VS)环境中打开并运行。通过分析这些源码,你可以学习到如何创建OPC连接,如何访问OPC服务器...
这个“OPCClient c#源码”项目提供了在Visual Studio 2010环境下开发和测试的OPC客户端的源代码,包含所有必要的DLL文件,对于学习和理解OPC客户端的实现非常有帮助。 OPC标准定义了一组COM(Component Object ...
C#开发的OPC客户端UA源码:稳定可靠,支持二次开发,详细注释助力VS编辑器源码解读,OPCClient_UA源码OPC客户端 UA客户端源码(c#开发) 为opcClient_UA版本,由C#开发,可二次开发。 另外有opcserver,opcclient的da,...
标题 "opcclient VB源码" 涉及到的是使用Visual Basic (VB) 开发OPC客户端的应用程序源代码。OPC(OLE for Process Control)是工业自动化领域中用于数据交换的标准接口,它允许不同软件应用程序之间进行通信,特别...
综上所述,这个"C#写的OPC Client源码"项目为初学者提供了一个宝贵的实践平台,可以深入理解OPC通信机制,同时提升C#编程技能。通过学习和实践,开发者将能够创建自己的OPC客户端应用,实现与其他自动化设备的有效...
在本“vc++ opc client源码”中,我们主要探讨的是如何利用Microsoft的Visual C++编程语言来实现一个OPC客户端,以与OPC服务器进行交互。 1. **OPC基础概念** - OPC是基于微软的COM/DCOM技术,为自动化设备和控制...
总之,OPCClient源码的分析和学习可以帮助我们深入了解OPC技术,掌握如何使用C#编程语言与西门子的OPC Server通信,这对于提升工业自动化领域的软件开发能力具有重要意义。同时,这也为我们提供了一个实例,展示如何...
9. **示例代码**:这个简单的OPC客户端程序很可能是为了教学目的,所以源码中会有清晰的注释和示例,帮助初学者理解如何实际操作OPC接口。 通过分析和学习这个OPC客户端的源代码,开发者可以掌握OPC通信的基本原理...
OpcClient,顾名思义,是实现OPC规范的客户端应用程序,主要用于从OPC服务器读取或写入数据。本资源提供了一个实现了OPC客户端功能的源码,支持远程连接和订阅机制,非常适合于需要与OPC服务器进行交互的项目。 OPC...
C#开发的OPCClient源码介绍:专业可靠、可二次开发,详细注释与测试视频,封装好的源码可供参考,OPCClient与OPCServer源码解析:C#开发的可二次开发稳定项目,含详细注释与测试视频,opcclient源码OPC客户端DA源码...
OPCClient_UA源码:C#开发的可二次开发OPC客户端UA客户端,VS编辑器兼容,行业应用广泛且稳定可靠,优质OPC客户端UA源码(C#开发,VS2010兼容,多行业应用,稳定可靠,含测试源码与详细注释),OPCClient_UA源码OPC...
opc client 简单易懂可以作为开发参考