3. 实现OPC 类工厂

     这节我们将介绍com类工厂的实现。

1) 准备工作:

     在OPC Server运行过程中,对应每一个OPC client,都会生成一个COPCServer对象,为了管理所有的OPC server对象,我们先创建一个OPC server的管理类CServerMgr.
     "Project->Add Class.. ->C++ class"
     CServerMgr头文件如下:

ContractedBlock.gifExpandedBlockStart.gifCode
 1 #pragma once
 2 
 3 #include "OPCServer.h"
 4 
 5 class CServerMgr
 6 
{
 7 public
:
 8     CServerMgr(void
);
 9     ~CServerMgr(void
);
10 

11     //methods
12     void AddServerToList(COPCServer* pServer);
13     void RemoveServerFromList(COPCServer*
 pServer);
14 

15     //members
16 public:
17     CTypedPtrList<CPtrList, COPCServer *>
 m_serverList;
18 };

     AddServerToList()实现:

ContractedBlock.gifExpandedBlockStart.gifCServerMgr::AddServerToList
1 void CServerMgr::AddServerToList(COPCServer* pServer)
2 
{
3     if
 (pServer)
4 
        m_serverList.AddTail(pServer);
5 }

     RomoveServerFromList() 实现:

ContractedBlock.gifExpandedBlockStart.gifCode
 1 void CServerMgr::RemoveServerFromList(COPCServer* pServer)
 2 
{
 3     if
 (pServer)
 4 
    {
 5         if (m_serverList.GetCount() > 0
)
 6 
        {
 7             POSITION pos =
 m_serverList.Find(pServer);
 8             if
 (pos)
 9 
                m_serverList.RemoveAt(pos);
10 
        }
11 
    }
12 }

     在ServerMgr.cpp文件中定义CServerMgr全局变量:
     CServerMgr     g_ServerMgr;

2) 实现OPC 类工厂

这里实现的类工厂继承IClassFactory。

类工厂定义如下:

ContractedBlock.gifExpandedBlockStart.gifCOPCClassFactory
 1 #pragma once
 2 #include "ocidl.h"
 3 
 4 class COPCClassFactory :
 5     public
 IClassFactory
 6 
{
 7 public
:
 8     COPCClassFactory(void
);
 9     ~COPCClassFactory(void
);
10 

11     //IUnknown interfaces
12     STDMETHODIMP         QueryInterface( REFIID iid, LPVOID* ppInterface);
13     STDMETHODIMP_(ULONG) AddRef( void
);
14     STDMETHODIMP_(ULONG) Release( void
);
15 

16 //IClassFactory interfaces
17     STDMETHODIMP         CreateInstance( LPUNKNOWN pUnkOuter, REFIID riid, LPVOID* ppvObject);
18 
    STDMETHODIMP         LockServer( BOOL fLock);
19 

20 private:
21 
    ULONG    m_lRefCount;
22 };

 

     现在我们来看看如何具体实现类工厂:

     a. 初始化引用计数
     m_lRefCount = 0;

     b. QueryInterface()

ContractedBlock.gifExpandedBlockStart.gifQueryInterface
 1 // QueryInterface()
 2 // Implementation of the standard IUnknown QueryInterface() function for the sample OPC class factory.

 3 
 4 STDMETHODIMP COPCClassFactory::QueryInterface( REFIID iid, LPVOID* ppInterface)
 5 
{
 6   if ( ppInterface ==
 NULL)
 7     return
 E_INVALIDARG;
 8 

 9   if ( iid == IID_IUnknown || iid == IID_IClassFactory) 
10 
  {
11     *ppInterface = this
;
12 
  }
13   else

14     *ppInterface = NULL;
15 

16   if*ppInterface )
17 
  {
18 
    AddRef();
19     return
 S_OK;
20 
  }
21 

22   return E_NOINTERFACE;
23 }

 

     c. AddRef()

ContractedBlock.gifExpandedBlockStart.gifAddRef
1 // AddRef()
2 // Implementaion of the standard IUnknown AddRef() function for the sample OPC class factory.

3 
4 STDMETHODIMP_(ULONG) COPCClassFactory::AddRef( void)
5 
{
6   return ++
m_lRefCount;
7 }

 

     d. Release()

ContractedBlock.gifExpandedBlockStart.gifRelease
 1 // Release()
 2 // Implementation of the standard IUnknown Release() function for the sample OPC class factory.

 3 
 4 STDMETHODIMP_(ULONG) COPCClassFactory::Release( void)
 5 
{
 6   ULONG currentCount = --
m_lRefCount;
 7   if ( currentCount == 0
)
 8     delete this
;
 9   return
 currentCount;
10 }

 

     e. CreateInstance()

    在"OPCClassFactory.cpp"定义:
     #include "ServerMgr.h"
     extern CServerMgr g_ServerMgr;

ContractedBlock.gifExpandedBlockStart.gifCreateInstance
 1 // CreateInstance()
 2 // This function creates an instance of the OPC sample server.

 3 STDMETHODIMP COPCClassFactory::CreateInstance( LPUNKNOWN pUnkOuter, REFIID riid, LPVOID* ppvObject)
 4 
{
 5   COPCServer* pServer = new
 COPCServer;
 6   if ( pServer ==
 NULL)
 7 
  {
 8     TRACE( "OPCClassFactory::CreateInstance() - Not enough memory to create OPC Server object, returning E_OUTOFMEMORY\n"
 );
 9     return
 E_OUTOFMEMORY;
10 
  }
11   //get requested interface

12   HRESULT hr = pServer->QueryInterface( riid, ppvObject);
13   if
 ( FAILED( hr))
14 
  {
15 
    delete pServer;
16 
  }
17   else

18   {
19 
      g_ServerMgr.AddServerToList(pServer);
20 
  }
21     return
 hr;
22 
}
23 

 

     f. LockServer()

ContractedBlock.gifExpandedBlockStart.gifLockServer
 1 // LockServer()
 2 //
 This is a standard implementation of the IClassFactory::LockServer() function that either
 3 //
 adds or removes a lock on the server.
 4 //
 This is very useful if our server is an inproc process.
 5 // The count determines whether the dll can be unloaded or not.

 6 STDMETHODIMP COPCClassFactory::LockServer( BOOL fLock)
 7 
{
 8   if
 ( fLock)
 9     g_dwLockCount++
;
10   else

11     g_dwLockCount--;
12 

13   return S_OK;
14 }

 

3) 注册类厂

     因为我们的server是进程外server,所以要调用CoRegisterClassObject注册类厂对象。
     a.  在"COPCTestServerApp"类中添加变量:
          IClassFactory* m_pFactory;
          DWORD m_dwRegisterID;
     并在构造函数初始化:
          m_pFactory = NULL;
          m_dwRegisterID = 0;

     b. 定义OPC server GUID
     在"OPCTestServer.cpp"中添加:
          //Server GUID
          // {2BBA92EA-809B-4717-B3F9-750422C937B2}
          DEFINE_GUID(CLSID_OPCTestServer, 0x2bba92ea, 0x809b, 0x4717, 0xb3, 0xf9, 0x75, 0x4, 0x22, 0xc9, 0x37, 0xb2);

     c. 在InitInstance()中添加:

ContractedBlock.gifExpandedBlockStart.gifCode
 1 //Register class object
 2     if (m_pFactory == NULL)
 3 
    {
 4         m_pFactory = new
 COPCClassFactory();
 5         m_pFactory->
AddRef();
 6 

 7         if (FAILED( CoRegisterClassObject( CLSID_OPCTestServer, 
 8                 m_pFactory, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &
m_dwRegisterID)))
 9 
        {
10             TRACE("CoRegisterClassObject Failed."
);
11             return
 FALSE;
12 
        }
13     }

          并注释掉前面在添加ATL支持时VC自动加入的code:
            //#if !defined(_WIN32_WCE) || defined(_CE_DCOM)
           // Register class factories via CoRegisterClassObject().
           //if (FAILED(_AtlModule.RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE)))
           // return FALSE;
           //#endif // !defined(_WIN32_WCE) || defined(_CE_DCOM)

     d. 在Exitinstance()中添加

ContractedBlock.gifExpandedBlockStart.gifCode
 1 //#if !defined(_WIN32_WCE) || defined(_CE_DCOM)
 2 //
    _AtlModule.RevokeClassObjects();
 3 //
#endif
 4 

 5 //Revoke class object
 6 if (m_pFactory)
 7 
{
 8 
    ::CoRevokeClassObject(m_dwRegisterID);
 9     m_pFactory->
Release();
10 }
     一定要注释掉:_AtlModule.RevokeClassObjects();
posted on 2008-10-06 18:25  CheneySHI 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/opc521/archive/2008/10/06/1304954.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值