一个OPC服务器的简单实例

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

首先我们先来看一下什么是OPC

OPC (OLE for Process Control——用于过程控制的OLE)是基于Microsoft公司的DNA (Distributed Internet Application)构架和COM(Component Object Model)技术的一个工业标准接口,是根据易于扩展性而设计的。

再来了解一下OPC的用途

OPC主要适用于过程控制和制造自动化等应用领域。OPC是以OLE/COM机制作为应用程序的通讯标准。OLE/COM是一种客户/服务器模式,具有语言无关性、代码重用性、易于集成性等优点。OPC规范了接口函数,不管现场设备以何种形式存在,客户都以统一的方式去访问,从而保证软件对客户的透明性,使得用户完全从低层的开发中脱离出来然后我们再来看看OPC Server的组成

一个设备的OPC Server主要有两部组成,一是OPC标准接口的实现;二是与硬件设备的通信模块。

实现OPC 标准接口

在这些接口中,IOPCServer 是OPC Server的主接口,通过它实现OPC Server在操作系统中的安装和注册。此接口是必须要实现的,其所有方法也必须实现。其它的接口都是可选的我们就不做介绍了,下面主要来介绍如何实现IOPCServer接口。

在IOPCServer接口中共有六个法:

1、IOPCServer::AddGroup

HRESULT AddGroup( [in, string] LPCWSTR szName,

[in] BOOL bActive,

[in] DWORD dwRequestedUpdateRate,

[in] OPCHANDLE hClientGroup,

[unique, in] LONG *pTimeBias,

[in] FLOAT * pPercentDeadband,

[in] DWORD dwLCID,

[out] OPCHANDLE * phServerGroup,

[out] DWORD *pRevisedUpdateRate,

[in] REFIID riid,

[out, iid_is(riid)] LPUNKNOWN * ppUnk ;

此方法是在OPC Server上建立一个组。下在我们来实现这个方法:

….

….

首先要对组名(szName)进行检查,看是否有效或是否已经有这个组。

if (szName != NULL)

{

RequestedName = szName;

if (RequestedName == ""

RequestedName = pSvrObject->DefaultGroupName();

}

else

RequestedName = pSvrObject->DefaultGroupName();

for (i=0; iNumbrGroups(); i++)

{

pGroup = pSvrObject->GetGroup(i);

if (RequestedName == pGroup->Name)

return (OPC_E_DUPLICATENAME);

}

这需要在内存中维护OPC Group(组)的列表(还要有OPC 项的列表)。

如果szName(组名)正确并且没有建立过该组,就开始根据传过来的参数进行组的建立,建立好后将该组加到自己的组列表中以备后用。

if ((dwRequestedUpdateRate == 0) || (dwRequestedUpdateRate < pApp->ServerTickRate)) ActualRate = pApp->ServerTickRate;

else

{

ActualRate = dwRequestedUpdateRate;

MinRate = pApp->ServerTickRate;

ActualRate += (MinRate/2);

ActualRate /= MinRate;

ActualRate *= MinRate;

}

if (pRevisedUpdateRate)

*pRevisedUpdateRate = ActualRate;

pGroup = new (COPCGroup);

if(pGroup == NULL)

return (E_OUTOFMEMORY);

pGroup->Name = RequestedName;

pGroup->pSvrObject = pSvrObject;

pGroup->MarkedForDeletion = FALSE;

pGroup->ClientGroupHandle = hClientGroup;

pGroup->UpdateRate = ActualRate;

pGroup->IsActive = bActive;

if (pPercentDeadband)

pGroup->Deadband = *pPercentDeadband;

else

pGroup->Deadband = 0.0;

pGroup->LCID = dwLCID;

if (pTimeBias)

pGroup->TimeBias = *pTimeBias;

else

{

_ftime( &timebuffer ;

pGroup->TimeBias = timebuffer.timezone;

相关文档
最新文档