COPCServer类继承IOPCServer接口,实现IOPCServer的所有接口。
1) OPC DA头文件
在开发opc server的过程中,我们要包含的头文件主要有:
u opcda.h: 定义IOPCServer, IOPCItemMgt, IOPCAsyncIO 等OPC DA接口;
u opcda_i.c : Classs ID 定义;
u opcError.h: OPC Error 类型定义;
u opccommon.h: 定义IOPCCommon,IOPCServerList等接口
u opccommon_i.c: Class ID 定义
这些头文件都可以直接从OPC 网站上面的分发包里面安装获得。为了方便大家使用,我把这些文件上传这里了。
https://files.cnblogs.com/opc521/OPCDAInclude.zip
NOTE:如果机器上以前没有注册过opcproxy.dll,一定要先注册这个dll,这是实现OPC DA接口定义及代理/存根的dll. 至于什么是代理/存根,大家请参阅其他的关于COM 和DCOM的书籍。
2)添加COPCServer 类定义
Project->Add Class -> C++ Class
![](https://images.cnblogs.com/cnblogs_com/opc521/GenerateOPServerClass.JPG)
VS 提示IOPCServer 没有找到,是否继续,按“Yes”继续。我们将在后面添加“IOPCServer”的定义。
NOTE:这里,为了方便统一管理生成COPCServer对象,我们没有从ATL 中的CComCoClass类派生。
将需要包含的头文件(opcda.h, opcda_i.c)拷到include目录下(solution 下面的新建的一个子文件夹),在“OPCServer.h”文件中添加:
#include "opcda.h"
编译一下,确保没有错误。
3)实现IUnknown 接口
IOPCServer继承IUnknown接口,所以COPCServer首先要实现IUnkonw接口。
a. 添加引用计数变量
private:
ULONG m_lRefCount;
b. 添加接口定义到OPCServer.h:
// the IUnknown Functions
STDMETHODIMP QueryInterface( REFIID iid, LPVOID* ppInterface);
STDMETHODIMP_(ULONG) AddRef( void);
STDMETHODIMP_(ULONG) Release( void);
c. 添加接口函数实现:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
IUnknown Interfaces
1 ////////////////////////////////////////////////////////////////////////////////////
2 STDMETHODIMP_(ULONG) COPCServer::AddRef( void)
3 {
4 return ++m_lRefCount;
5 }
6
7 ////////////////////////////////////////////////////////////////////////////////////
8 STDMETHODIMP_(ULONG) COPCServer::Release( void)
9 {
10 ULONG currentCount = --m_lRefCount;
11
12 // If no references left for this server
13 if ( currentCount == 0)
14 {
15 // Then delete this server.
16 delete this;
17 }
18 return currentCount;
19 }
20
21 ////////////////////////////////////////////////////////////////////////////////////
22 STDMETHODIMP COPCServer::QueryInterface( REFIID iid, LPVOID* ppInterface)
23 {
24 // check valid pointer
25 if ( ppInterface == NULL)
26 return E_INVALIDARG;
27
28 // default return is NULL in case of error
29 *ppInterface = NULL;
30
31 if ( iid == IID_IUnknown )
32 {
33 *ppInterface = (IUnknown*) this;
34 }
35
36 else if ( iid == IID_IOPCServer)
37 {
38 *ppInterface = (IOPCServer*) this;
39 }
40
41 if ( *ppInterface == NULL)
42 return E_NOINTERFACE;
43
44 AddRef();
45 return S_OK;
46 }
47
4. 添加IOPCServer接口函数
a. 在"opcserver.h"中添加函数定义
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
IOPCServer Functions
1 // the IOPCServer Functions
2 STDMETHODIMP GetStatus(
3 OPCSERVERSTATUS** ppServerStatus);
4 STDMETHODIMP GetErrorString(
5 HRESULT hr,
6 LCID locale,
7 LPWSTR *ppstring);
8 STDMETHODIMP AddGroup(
9 LPCWSTR szName,
10 BOOL bActive,
11 DWORD dwRequestedUpdateRate,
12 OPCHANDLE hClientGroup,
13 LONG *pTimeBias,
14 FLOAT *pPercentDeadband,
15 DWORD dwLCID,
16 OPCHANDLE *phServerGroup,
17 DWORD *pRevisedUpdateRate,
18 REFIID riid,
19 LPUNKNOWN *ppUnk
20 );
21 STDMETHODIMP GetGroupByName(
22 LPCWSTR szGroupName,
23 REFIID riid, LPUNKNOWN *ppUnk);
24 STDMETHODIMP RemoveGroup(
25 OPCHANDLE groupHandleID,
26 BOOL bForce);
27
28 STDMETHODIMP CreateGroupEnumerator(
29 OPCENUMSCOPE dwScope,
30 REFIID riid,
31 LPUNKNOWN *ppUnk
32 );
b. 在"OPCServer.cpp"中添加函数实现
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
//////////////////////////////////////////////////////////////////////////////////
// the IOPCServer Functions
STDMETHODIMP COPCServer::GetStatus( OPCSERVERSTATUS** ppServerStatus)
{
return S_OK;
}
//////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COPCServer::GetErrorString( HRESULT hr, LCID locale,
LPWSTR *ppstring)
{
return S_OK;
}
//////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COPCServer::AddGroup(
LPCWSTR szName,
BOOL bActive,
DWORD dwRequestedUpdateRate,
OPCHANDLE hClientGroup,
LONG *pTimeBias,
FLOAT *pPercentDeadband,
DWORD dwLCID,
OPCHANDLE *phServerGroup,
DWORD *pRevisedUpdateRate,
REFIID riid,
LPUNKNOWN *ppUnk
)
{
return S_OK;
}
//////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COPCServer::GetGroupByName(
LPCWSTR szGroupName,
REFIID riid, LPUNKNOWN *ppUnk)
{
return S_OK;
}
//////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COPCServer::RemoveGroup( OPCHANDLE groupHandleID,
BOOL bForce)
{
return S_OK;
}
//////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COPCServer::CreateGroupEnumerator(
OPCENUMSCOPE dwScope,
REFIID riid,
LPUNKNOWN *ppUnk
)
{
return S_OK;
}
这些接口函数现在都是空函数,我们会在以后的章节中逐步实现这些函数。