初始化COM类,在FinalConstruct与构造函数中初始化有何区别

There   are   advantages   to   performing   initialization   in   FinalConstruct   rather   than   the   constructor   of   your   class:  

      You   cannot   return   a   status   code   from   a   constructor,   but   you   can   return   an   HRESULT   by   means   of   FinalConstruct 's   return   value.   When   objects   of   your   class   are   being   created   using   the   standard   class   factory   provided   by   ATL,   this   return   value   is   propagated   back   to   the   COM   client   allowing   you   to   provide   them   with   detailed   error   information.  

      You   cannot   call   virtual   functions   through   the   virtual   function   mechanism   from   the   constructor   of   a   class.   Calling   a   virtual   function   from   the   constructor   of   a   class   results   in   a   statically   resolved   call   to   the   function   as   it   is   defined   at   that   point   in   the   inheritance   hierarchy.   Calls   to   pure   virtual   functions   result   in   linker   errors.  

      Your   class   is   not   the   most   derived   class   in   the   inheritance   hierarchy   —   it   relies   on   a   derived   class   supplied   by   ATL   to   provide   some   of   its   functionality.   There   is   a   good   chance   that   your   initialization   will   need   to   use   the   features   provided   by   that   class   (this   is   certainly   true   when   objects   of   your   class   need   to   aggregate   other   objects),   but   the   constructor   in   your   class   has   no   way   to   access   those   features.   The   construction   code   for   your   class   is   executed   before   the   most   derived   class   is   fully   constructed.  

However,   FinalConstruct   is   called   immediately   after   the   most   derived   class   is   fully   constructed   allowing   you   to   call   virtual   functions   and   use   the   reference-counting   implementation   provided   by   ATL.  

----From   MSDN

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个使用VC2019开发OPC Server的示例代码: ```cpp #include <windows.h> #include <tchar.h> #include <opcda.h> #include <opcerror.h> #include <atlbase.h> class CMyOPCServer : public CComObjectRootEx<CComMultiThreadModel>, public IOPCServer { public: DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct() { return S_OK; } void FinalRelease() { } BEGIN_COM_MAP(CMyOPCServer) COM_INTERFACE_ENTRY(IOPCServer) END_COM_MAP() // IOPCServer methods STDMETHODIMP AddGroup(LPCWSTR szName, BOOL bActive, DWORD dwRequestedUpdateRate, OPCHANDLE hClientGroup, LONG* pTimeBias, FLOAT* pPercentDeadband, DWORD dwLCID, OPCHANDLE* phServerGroup, DWORD* pRevisedUpdateRate, REFIID riid, LPUNKNOWN* ppUnk) { // TODO: Implement AddGroup method return E_NOTIMPL; } STDMETHODIMP GetErrorString(HRESULT dwError, LCID dwLocale, LPWSTR* ppString) { // TODO: Implement GetErrorString method return E_NOTIMPL; } STDMETHODIMP GetGroupByName(LPCWSTR szName, REFIID riid, LPUNKNOWN* ppUnk) { // TODO: Implement GetGroupByName method return E_NOTIMPL; } STDMETHODIMP GetStatus(OPCSERVERSTATUS** ppServerStatus) { // TODO: Implement GetStatus method return E_NOTIMPL; } STDMETHODIMP RemoveGroup(OPCHANDLE hServerGroup, BOOL bForce) { // TODO: Implement RemoveGroup method return E_NOTIMPL; } STDMETHODIMP CreateGroupEnumerator(DWORD dwScope, REFIID riid, LPUNKNOWN* ppUnk) { // TODO: Implement CreateGroupEnumerator method return E_NOTIMPL; } }; int _tmain(int argc, TCHAR* argv[]) { HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if (FAILED(hr)) { _tprintf(_T("Failed to initialize COM library: 0x%08X\n"), hr); return -1; } hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); if (FAILED(hr)) { _tprintf(_T("Failed to initialize security: 0x%08X\n"), hr); CoUninitialize(); return -1; } CComObject<CMyOPCServer>* pServer; hr = CComObject<CMyOPCServer>::CreateInstance(&pServer); if (FAILED(hr)) { _tprintf(_T("Failed to create OPC server object: 0x%08X\n"), hr); CoUninitialize(); return -1; } hr = pServer->QueryInterface(IID_IOPCServer, (LPVOID*)&pServer); if (FAILED(hr)) { _tprintf(_T("Failed to get IOPCServer interface: 0x%08X\n"), hr); CoUninitialize(); return -1; } // TODO: Register OPC server MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } // TODO: Unregister OPC server pServer->Release(); CoUninitialize(); return 0; } ``` 请注意,此代码仅提供了一个框架,需要根据具体的OPC Server实现进行修改和扩展。例如,您需要实现IOPCServer接口的所有方法,并在TODO注释的位置添加注册和注销OPC服务器的代码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值