C++中COM组件管理思想实践

news2024/11/19 0:38:44

在开发一个产品时,其往往有很多子模块,子业务和子功能,这些都可以抽象成组件(C++中本质表现就是一个类)。但是如何更好的管理这些类的对象呢?我们可以借鉴微软的COM组件思想来进行对象的注册,创建,销毁等管理工作。本文以某产品(产品业务为Business)的子功能AAAAAA为例,探讨一下COM组件思想在开发中的应用。

目录

1.类图

 2.代码结构

3.代码实现

4.调用测试


1.类图

 2.代码结构

3.代码实现

3.1 aaaaaa_com_factory.h / aaaaaa_com_factory.cpp

#include "business_engine_factory.h"

class CAAAAAAComFactory : public VBusinessFactory
{
public:
    /**
     *    组件接口创建方法
     *    @param riid            [in] 接口ID
     *    @param ppv            [in/out] 组件接口指针
     *
     *    @return            返回创建状态
     *    @note
     */
    static BUSINESS_VHRESULT CreateInstanceSPtr(const VBUSINESSCUID& iid, CompSPtr& ppv);
};
#include "aaaaaa_com_factory.h"
#include "aaaaaa_if.h"
#include "comserver_control.h"
#include "comserver_define.h"

VBusinessFactory::~VBusinessFactory(){}

BUSINESS_VHRESULT CAAAAAAComFactory::CreateInstanceSPtr(const VBUSINESSCUID& iid, CompSPtr& ppv)
{
    BUSINESS_VHRESULT result = BUSINESS_VE_NOTIMPL;
    // 识别类型
    if (iid.find(CComServerControl::CompClsID(ComServer_Basic_AAAAAA)) >= 0)
    {
        //使用aaaaaa的基类
        std::shared_ptr<CAAAAAAInterface> spMapMatch = std::make_shared<CAAAAAA>();
        if (spMapMatch == nullptr) {
            result = BUSINESS_VE_FAIL;
        } else {
            ppv = spMapMatch;
            result = BUSINESS_VS_OK;
        }
    }

    return result;
}

3.2 aaaaaa_com_interface.h

#pragma once

#include <iostream>
#include "business_engine_interface.h"

class CAAAAAAInterface : public VBusinessInterface
{
public:
    virtual ~CAAAAAAInterface();
    virtual void fun1();
    virtual void fun2();
};

using AAAAAAPtr = std::shared_ptr<CAAAAAAInterface>;
#define GetAAAAAAPtr(com_ptr) (std::dynamic_pointer_cast<CAAAAAAInterface>(com_ptr))

3.3 aaaaaa_if.h / aaaaaa_if.cpp

#pragma once
#include "aaaaaa_com_interface.h"

class CAAAAAA : public CAAAAAAInterface
{
public:
	CAAAAAA() {

    }

	~CAAAAAA() {

    }

    void fun1() {
        std::cout << "fun1" << std::endl;
    }

    void fun2() {
        std::cout << "fun2" << std::endl;
    }
};
#include "aaaaaa_if.h"

VBusinessInterface::~VBusinessInterface(){}

CAAAAAAInterface::~CAAAAAAInterface() {};
void CAAAAAAInterface::fun1() {}
void CAAAAAAInterface::fun2() {}

3.4 business_control_impl.h / business_control_impl.cpp

#pragma once

#include "business_control_interface.h"
#include "business_engine_interface.h"
#include "comserver_control.h"
#include "shared_pointer_guard.h"

class CBusinessControl :  public CBusinessControlInterface , public SharedPointerGuard<CBusinessControl> {
public:
    CBusinessControl();
    virtual ~CBusinessControl();
    
public:
    static  void GlobalInit();
    // 注册组件实例创建方法
    static  void RegisterComponent(int type, VBusinessComFactoryFuncSPtr factoryFunc); 
    virtual bool Init(const std::string & config);
    virtual bool UnInit();
    virtual bool InitComponent(const std::string  & config, int type);


    virtual bool GetComServerSPtr(const int& type, std::shared_ptr<VBusinessInterface>& compSPtr);
    virtual bool GetComServerSPtr(const int& type, const std::string& vID, std::shared_ptr<VBusinessInterface>& compSPtr);

public:
    CComServerControl comServerControl;

private:
    static bool                            _bInit; 
    static std::recursive_mutex            _mutex;
};
#include "business_control_impl.h"

CBusinessControlInterface::CBusinessControlInterface() {};
CBusinessControlInterface::~CBusinessControlInterface() {};

bool CBusinessControl::_bInit = false; 
std::recursive_mutex    CBusinessControl::_mutex;

CBusinessControl::CBusinessControl() {
    CBusinessControl::GlobalInit();
}

CBusinessControl::~CBusinessControl() {

}
    
void CBusinessControl::GlobalInit() {
    if (_bInit) {
        return;
    }
    //别的初始胡...
    CComServerControl::Init();
    _bInit = true;
}

void CBusinessControl::RegisterComponent(int type, VBusinessComFactoryFuncSPtr factoryFunc) {
    CComServerControl::RegistComponent(type, factoryFunc, false);
}

bool CBusinessControl::Init(const std::string & config) {
    {
        std::lock_guard<std::recursive_mutex> guard(_mutex);
        SetID("8888");
        //调用shared_from_this的类必须至少有一个share_ptr指向它。而且必须是new方式创建的,std::make_shraed还不可以
        comServerControl.SetBusinessControl(shared_this());
    }

    return true;
}

bool CBusinessControl::UnInit() {
    return true;
}

bool CBusinessControl::InitComponent(const std::string  & config, int type) {
    return true;
}

bool CBusinessControl::GetComServerSPtr(const int& type, std::shared_ptr<VBusinessInterface>& compSPtr) {
    CBusinessControl::GlobalInit();
    return comServerControl.GetComServerSPtr(type, compSPtr);
}

bool CBusinessControl::GetComServerSPtr(const int& type, const std::string& vID, std::shared_ptr<VBusinessInterface>& compSPtr) {
    return true;
}

3.5 business_control_interface.h

#ifndef _business_control_interface_h_
#define _business_control_interface_h_

#include <memory>
#include <string>

//注意:此处通过include引用头文件会出现编译错误
//#include "business_engine_interface.h"
class VBusinessInterface;

typedef std::string CBusinessControlID;

//业务控制接口类
class CBusinessControlInterface {
    
public:
    CBusinessControlInterface();
    virtual ~CBusinessControlInterface();
    CBusinessControlInterface(const CBusinessControlInterface&) = delete;
    CBusinessControlInterface& operator=(const CBusinessControlInterface&) = delete;
    
public:
    const CBusinessControlID ID() const { return _id; }
    void SetID(const CBusinessControlID &id_) { _id = id_; }
    
public:
    virtual bool Init(const std::string & config) = 0;
    virtual bool UnInit() = 0;
    virtual bool InitComponent(const std::string  & config, int type) = 0;
    
    /**
     * 组件获取
     */
    virtual bool GetComServerSPtr(const int& type, std::shared_ptr<VBusinessInterface>& compSPtr) = 0;
    virtual bool GetComServerSPtr(const int& type, const std::string& vID, std::shared_ptr<VBusinessInterface>& compSPtr) = 0;
    
private:
    CBusinessControlID _id;
};

typedef std::shared_ptr<CBusinessControlInterface> BusinessControlSPtr;

#endif

3.6 business_engine_comserver.h / business_engine_comserver.cpp

#pragma once
#include <mutex>
#include <map>

#include "business_engine_interface.h"

// 任意类型
typedef void*				LPVVoid;	

class CVBusinessComServer
{
public:
    /**
     *    初始化组件服务
     */
    static BUSINESS_VHRESULT InitComServer();
    
    /**
     *    反初始化组件服务
     *
     */
    static BUSINESS_VHRESULT UnitComServer();
    

    /**
     *    创建组件并获取接口
     *    @param rclsid        [in] 组件ID
     *    @param factoryfunc    [in] 组件工厂
     */
    static BUSINESS_VHRESULT ComRegist(const VBUSINESSCLSID& rclsid, const VBusinessComFactoryFuncSPtr factoryfunc);
     
    /**
     *    创建组件并获取接口
     *    @param rclsid        [in] 组件ID
     *    @param riid            [in] 接口ID
     *    @param ppv            [in/out] 组件接口指针
     *
     *    @return            返回创建状态
     *    @note
     */
    static BUSINESS_VHRESULT ComCreateInstanceSPtr(const VBUSINESSCLSID& rclsid, const VBUSINESSCUID& iid, CompSPtr& ppv);
    
private:
    static std::mutex                        m_mutex;                    // 多线程互斥锁
    static std::map<std::string, LPVVoid>    m_CLSID2FFMap;      // 组件ID和组件工厂函数指针对照表
};
#include "business_engine_comserver.h"
#include "business_engine_factory.h"


BUSINESS_VHRESULT CVBusinessComServer::InitComServer() {
    return BUSINESS_VS_OK;
}
    
BUSINESS_VHRESULT CVBusinessComServer::UnitComServer(){
    return BUSINESS_VS_OK;    
}
    
BUSINESS_VHRESULT CVBusinessComServer::ComRegist(const VBUSINESSCLSID& rclsid, const VBusinessComFactoryFuncSPtr factoryfunc){
    LPVVoid pValue = NULL;
    if (m_CLSID2FFMap.end() == m_CLSID2FFMap.find(rclsid)) {
        m_CLSID2FFMap[rclsid] = (LPVVoid)factoryfunc;
        return BUSINESS_VS_OK;
    }
    
    return BUSINESS_VE_UNEXPECTED;  
}
     
BUSINESS_VHRESULT CVBusinessComServer::ComCreateInstanceSPtr(const VBUSINESSCLSID& rclsid, const VBUSINESSCUID& iid, CompSPtr& ppv){
    BUSINESS_VHRESULT hresult;
    VBusinessComFactoryFuncSPtr pValue = nullptr;
    if (m_CLSID2FFMap.end() != m_CLSID2FFMap.find(rclsid))
    {
        pValue = (VBusinessComFactoryFuncSPtr)m_CLSID2FFMap[rclsid];
        hresult = pValue(iid, ppv);
    }
    return BUSINESS_VS_OK;
}

std::map<std::string, LPVVoid>    CVBusinessComServer::m_CLSID2FFMap;   

3.7 business_engine_factory.h

#include "business_engine_comserver.h"

class VBusinessFactory
{
public:
    virtual ~VBusinessFactory();
        /**
     *    组件接口创建方法
     *    @param riid            [in] 接口ID
     *    @param ppv            [in/out] 组件接口指针
     *
     *    @return            返回创建状态
     *    @note
     */
    virtual BUSINESS_VHRESULT CreateInstance1(const VBUSINESSCUID& iid, LPVVoid *ppv) = 0;
};

3.8 comserver_config.h

#pragma once

//编译时期控制宏

#define STATIC_ENABLE_AAAAAA    1
#define STATIC_ENABLE_BBBBBB    1

//运行期控制模版
typedef struct _ComServerDynamicConfig
{
    bool DY_ENABLE_AAAAAA;
    bool DY_ENABLE_BBBBBB;
   
   _ComServerDynamicConfig()
    {
#ifdef STATIC_ENABLE_AAAAAA 
        DY_ENABLE_AAAAAA = true;
#else
        DY_ENABLE_AAAAAA = false;
#endif
#ifdef STATIC_ENABLE_BBBBBB
        DY_ENABLE_BBBBBB = true;
#else
        DY_ENABLE_BBBBBB = false;
#endif
    };
    
    void Reset()
    {
        #ifdef STATIC_ENABLE_AAAAAA
                DY_ENABLE_AAAAAA = true;
        #else
                DY_ENABLE_AAAAAA = false;
        #endif
        #ifdef STATIC_ENABLE_BBBBBB
                DY_ENABLE_BBBBBB = true;
        #else
                DY_ENABLE_BBBBBB = false;
        #endif
       
    };
    
    void Init(_ComServerDynamicConfig& clConfig)
    {
#ifdef STATIC_ENABLE_AAAAAA
        DY_ENABLE_AAAAAA = clConfig.DY_ENABLE_AAAAAA;
#endif
#ifdef STATIC_ENABLE_BBBBBB
        DY_ENABLE_BBBBBB = clConfig.DY_ENABLE_BBBBBB;
#endif
    };
}ComServerDynamicConfig;

3.9 comserver_control.h / comserver_control.cpp

#pragma once

#include <string>
#include <map>
#include <mutex>
#include "business_control_interface.h"
#include "business_engine_interface.h"
#include "comserver_config.h"

typedef std::map<std::string, CompSPtr> CompSPtrMap;
typedef std::map<std::string, CompSPtrMap> CompMap;
typedef std::map<int, VBusinessComFactoryFuncSPtr> CompFactoryMap;

class CComServerControl
{
public:
    CComServerControl();
   
    ~CComServerControl();
    
public:
    static bool Init();
        
    static void UnInit();

    static bool InitComponents();
       
    static void UnInitComponents();
        
    static bool LoadDynamicConfig(const std::string& clDyJson);
    
    static bool SetDefaultCompControl(BusinessControlSPtr pBusinessControl);
    
    static bool RegistComponent(const int& type, const VBusinessComFactoryFuncSPtr& factoryFunc, const bool& isComRegist = true);
    
    static bool AddDefaultComponent(const int& type, const VBusinessComFactoryFuncSPtr& factoryFunc, CompSPtr& compSPtr);
    
    static bool GetDefaultComServerSPtr(const int& type, CompSPtr& compSPtr);
    
  
    static bool CreateCompSPtr(const int& type, const std::string& tag, CompSPtr& compSPtr);
    

    static std::string CompClsID(const int& type);
    static std::string CompVID(const int& type);
    static std::string CompVID(const int& type, const std::string& tag);
    
public:
    bool AddComponent(const int& type, const VBusinessComFactoryFuncSPtr& factoryFunc, CompSPtr& compSPtr);
    bool AddComponent(const int& type, const VBusinessComFactoryFuncSPtr& factoryFunc, const std::string& tag, CompSPtr& compSPtr);
    
    bool SetBusinessControl(BusinessControlSPtr pBusinessControl);
    
    bool GetComServerSPtr(const int& type, CompSPtr& compSPtr);
    bool GetComServerSPtr(const int& type, const std::string& vID, CompSPtr& compSPtr);
    
private:
    static bool AddDefaultComponent(const int& type, const VBusinessComFactoryFuncSPtr& factoryFunc, const std::string& clsID, const std::string& vID, CompSPtr& compSPtr);
    
    static bool RegistComponent(const int& type, const VBusinessComFactoryFuncSPtr& factoryFunc, const std::string& clsID, const bool& isComRegist = true);
    
    bool AddComponent(const int& type, const VBusinessComFactoryFuncSPtr& factoryFunc, const std::string& clsID, const std::string& vID, CompSPtr& compSPtr);
    
public:
    static ComServerDynamicConfig    m_clDyConfig;  /**< 组件动态化配置表 */

private:

    static CompMap                          _compMapDefault;            /**< 组件容器*/
    static std::mutex                       _Initmutex;                 /**<初始化锁*/
    static CompFactoryMap                   _compFactoryMap;            /**< 组件工厂类映射*/
    static BusinessControlSPtr              _pDefaultBusinessControl;   /**< 默认业务控制control实例*/
    BusinessControlSPtr                     _pBusinessControl;              /**< 业务control实例*/
    CompMap                                 _compMap;                   /**< 类型到clsID映射*/
};
#include <vector>
#include <tuple>
#include "comserver_control.h"
#include "aaaaaa_com_interface.h"
#include "business_engine_comserver.h"
#include "comserver_define.h"
#include "aaaaaa_com_factory.h"


CComServerControl::CComServerControl() {
    CComServerControl::Init();
}
   
CComServerControl::~CComServerControl() {

}
    
bool CComServerControl::Init() {
    std::vector<std::tuple<int, VBusinessComFactoryFuncSPtr>> comFactoryConfigs = {
      std::make_tuple(ComServer_Basic_AAAAAA, (VBusinessComFactoryFuncSPtr)CAAAAAAComFactory::CreateInstanceSPtr)
    };
    
    for (const auto &t : comFactoryConfigs) {
        _compFactoryMap.insert(CompFactoryMap::value_type(std::get<0>(t), std::get<1>(t)));
    }

    InitComponents();
    return true;
}
        
void CComServerControl::UnInit() {

}

bool CComServerControl::InitComponents() {
    bool bRet = true;
    std::vector<std::tuple<int, bool>> comConfigs = {
        std::make_tuple(ComServer_Basic_AAAAAA, m_clDyConfig.DY_ENABLE_AAAAAA),
    };
    CompSPtr compSPtr;
    for(const auto &t : comConfigs)
    {
        int type = std::get<0>(t);
        if (std::get<1>(t) && _compFactoryMap.find(type) != _compFactoryMap.end())
        {
            if (!AddDefaultComponent(type, _compFactoryMap[type], compSPtr))
            {
                bRet = false;
                break;
            }
        }
    }
    return bRet;
}
       
void CComServerControl::UnInitComponents() {

}
        
bool CComServerControl::LoadDynamicConfig(const std::string& clDyJson) {
    return true;
}
    
bool CComServerControl::SetDefaultCompControl(BusinessControlSPtr pBusinessControl) {
     // 第一个创建的
    if (_pDefaultBusinessControl) return true;
    
    for (auto &kv : _compMapDefault) {
        for (auto &sub : kv.second) {
            sub.second->SetBusinessControl(pBusinessControl);
        }
    }
    _pDefaultBusinessControl = pBusinessControl;
    return true;
}
    
bool CComServerControl::RegistComponent(const int& type, const VBusinessComFactoryFuncSPtr& factoryFunc, const bool& isComRegist) {
    return RegistComponent(type, factoryFunc, CompClsID(type), isComRegist);
}
    
bool CComServerControl::AddDefaultComponent(const int& type, const VBusinessComFactoryFuncSPtr& factoryFunc, CompSPtr& compSPtr) {
    return AddDefaultComponent(type, factoryFunc, CompClsID(type), CompVID(type), compSPtr);
}
    
bool CComServerControl::GetDefaultComServerSPtr(const int& type, CompSPtr& compSPtr) {
    return true;
}
    
bool CComServerControl::CreateCompSPtr(const int& type, const std::string& tag, CompSPtr& compSPtr) {
    return true;
}
    
std::string CComServerControl::CompClsID(const int& type) {
    std::string strID = "";
    strID += "comp_";
    strID += std::to_string(type);
    return strID;
}

std::string CComServerControl::CompVID(const int& type) {
    return CompVID(type, "");
}

std::string CComServerControl::CompVID(const int& type, const std::string& tag) {
    std::string strID = "";
    strID += CompClsID(type);
    if (!tag.empty()) {
        strID.append("_");
        strID.append(tag);
    }
    strID += "_instance";
    return strID;
}
    
bool CComServerControl::AddComponent(const int& type, const VBusinessComFactoryFuncSPtr& factoryFunc, CompSPtr& compSPtr) {
    std::string clsID = CompClsID(type);

    std::string tag = "";
    if (_pBusinessControl)
    {
        tag = _pBusinessControl->ID().c_str();
    }
    std::string vID = CompVID(type, tag);
    return AddComponent(type, factoryFunc, clsID, vID, compSPtr);
}

bool CComServerControl::AddComponent(const int& type, const VBusinessComFactoryFuncSPtr& factoryFunc, const std::string& tag, CompSPtr& compSPtr) {
    std::string clsID = CompClsID(type);
    std::string vID = CompVID(type, tag);
    return AddComponent(type, factoryFunc, clsID, vID, compSPtr);
}
    
bool CComServerControl::SetBusinessControl(BusinessControlSPtr pBusinessControl) {
    _pBusinessControl = pBusinessControl;
    SetDefaultCompControl(pBusinessControl);
    return true;
}
    
bool CComServerControl::GetComServerSPtr(const int& type, CompSPtr& compSPtr) {
    bool bRet = GetComServerSPtr(type,
                            CompVID(type, _pBusinessControl->ID().c_str()),
                            compSPtr
                            );
    if (!bRet) {
        bRet = GetComServerSPtr(type,
                            CompVID(type),
                            compSPtr
                            );
    }
     
    return bRet;
}

bool CComServerControl::GetComServerSPtr(const int& type, const std::string& vID, CompSPtr& compSPtr) {
    bool bRet = false;
    std::string clsID = CompClsID(type);
    do{
        if (vID == CompVID(type))
        {
            if (_compMapDefault.find(clsID) == _compMapDefault.end()) break;
            if (_compMapDefault[clsID].find(vID) == _compMapDefault[clsID].end()) break;
            compSPtr = _compMapDefault[clsID][vID];
        }
        else
        {
            if (_compMap.find(clsID) == _compMap.end()) break;
            if (_compMap[clsID].find(vID) == _compMap[clsID].end()) break;
            compSPtr = _compMap[clsID][vID];
        }
        bRet = true;
    }while (0);
    
    return bRet;
}
    
bool CComServerControl::AddDefaultComponent(const int& type, const VBusinessComFactoryFuncSPtr& factoryFunc, const std::string& clsID, const std::string& vID, CompSPtr& compSPtr) {
    bool bRet = false;
    if (!RegistComponent(type, factoryFunc, clsID)) return bRet;
    if (clsID == "" || vID == "") return bRet;
    
    if (_compMapDefault.find(clsID) == _compMapDefault.end())
    {
        CompSPtrMap subCompMap;
        _compMapDefault.insert(CompMap::value_type(clsID, subCompMap));
    }
    
    std::map<std::string, CompSPtr> &subCompMap = _compMapDefault[clsID];
    if (subCompMap.find(vID) == subCompMap.end())
    {
        CompSPtr compSptr;
        if (CVBusinessComServer::ComCreateInstanceSPtr(clsID, vID, compSptr) == BUSINESS_VS_OK)
        {
            compSptr->SetBusinessControl(_pDefaultBusinessControl);
            subCompMap.insert(CompSPtrMap::value_type(vID, compSptr));
            bRet = true;
        }
    }
    return bRet;
}
    
bool CComServerControl::RegistComponent(const int& type, const VBusinessComFactoryFuncSPtr& factoryFunc, const std::string& clsID, const bool& isComRegist) {
    _compFactoryMap[type] = factoryFunc;
    if (isComRegist)
    {
        return CVBusinessComServer::ComRegist(clsID, factoryFunc) == BUSINESS_VS_OK;
    }
    return true;
}
    
bool CComServerControl::AddComponent(const int& type, const VBusinessComFactoryFuncSPtr& factoryFunc, const std::string& clsID, const std::string& vID, CompSPtr& compSPtr) {
    bool bRet = false;
    if (!RegistComponent(type, factoryFunc, clsID)) return bRet;
    if (clsID == "" || vID == "") return bRet;
    
    if (_compMap.find(clsID) == _compMap.end())
    {
        CompSPtrMap subCompMap;
        _compMap.insert(CompMap::value_type(clsID, subCompMap));
    }
    
    std::map<std::string, CompSPtr> &subCompMap = _compMap[clsID];
    if (subCompMap.find(vID) == subCompMap.end())
    {
        if (CVBusinessComServer::ComCreateInstanceSPtr(clsID, vID, compSPtr) == BUSINESS_VS_OK)
        {
            compSPtr->SetBusinessControl(_pBusinessControl);
            subCompMap.insert(CompSPtrMap::value_type(vID, compSPtr));
            bRet = true;
        }
    }
    return bRet;
}

ComServerDynamicConfig    CComServerControl::m_clDyConfig;

CompMap     CComServerControl::_compMapDefault;
std::mutex     CComServerControl::_Initmutex;
CompFactoryMap CComServerControl::_compFactoryMap;
BusinessControlSPtr  CComServerControl::_pDefaultBusinessControl; 

3.10 comserver_define.h

#pragma once

typedef enum _ComServer_Basic_Enum
{
    ComServer_Basic_Invalid = -1,
    ComServer_Basic_AAAAAA, 
    ComServer_Basic_BBBBBB                       
}ComServer_Basic_Enum;

3.11 shared_pointer_guard.h

#pragma once

#include <memory>
#include <functional>

template<typename TActual>
class SharedPointerGuard : public std::enable_shared_from_this<SharedPointerGuard<TActual>>
{
    typedef std::shared_ptr<TActual> Handle;
    typedef std::weak_ptr<TActual> WeakHandle;
    
protected:
    const Handle shared_this() {
        return std::static_pointer_cast<TActual>(this->shared_from_this());
    }
    
    template<typename T, typename ...TArgs>
    std::function<T(TArgs...)> this_guard(const std::function<T(TArgs...)> &func) {
        WeakHandle weak_handle = shared_this();
        std::function<T(TArgs...)> wrapper = [weak_handle, func](TArgs&&... args) {
            if (Handle handle = weak_handle.lock()) {
                return func(std::forward<TArgs>(args)...);
            }
            return T();
        };
        return wrapper;
    }
    
    template<typename ...TArgs>
    std::function<void(TArgs...)> this_guard(const std::function<void(TArgs...)> &func) {
        WeakHandle weak_handle = shared_this();
        std::function<void(TArgs...)> wrapper = [weak_handle, func](TArgs&&... args) {
            if (Handle handle = weak_handle.lock()) {
                func(std::forward<TArgs>(args)...);
            }
        };
        return wrapper;
    }
    
    std::function<void()> this_guard(const std::function<void()> &func) {
        WeakHandle weak_handle = shared_this();
        std::function<void()> wrapper = [weak_handle, func] {
            if (Handle handle = weak_handle.lock()) {
                func();
            }
        };
        return wrapper;
    }
};

3.12 test_com.cpp

#include <iostream>
#include "business_control_impl.h"
#include "comserver_define.h"
#include "aaaaaa_com_factory.h"
#include "aaaaaa_com_interface.h"

using namespace std;

int main(int argc, char* argv[]) {
    std::cout << "test com compent ...." << std::endl;

    //注册组件
    CBusinessControl::RegisterComponent(ComServer_Basic_AAAAAA, (VBusinessComFactoryFuncSPtr)CAAAAAAComFactory::CreateInstanceSPtr);

    //创建业务控制总对象,构造函数中COM组件管理初始化
    //BusinessControlSPtr businessControl = std::make_shared<CBusinessControl>();
    BusinessControlSPtr businessControl(new CBusinessControl());
    //业务初始化
    businessControl->Init("");
    //获取com类型的业务组件
    CompSPtr ptr;
    businessControl->GetComServerSPtr(ComServer_Basic_AAAAAA, ptr);
    AAAAAAPtr pclAAAAAA = GetAAAAAAPtr(ptr);
    if(!pclAAAAAA)
    {
        std::cout << "pclAAAAAA is nullptr" << std::endl;
        return -1;
    }

    //调用组件
    pclAAAAAA->fun1();
    pclAAAAAA->fun2();
    
    return 0;
}

3.13 Makefile

test : test_com.o aaaaaa_if.o business_control_impl.o aaaaaa_com_factory.o business_engine_comserver.o comserver_control.o
	g++ -g -o test test_com.o  aaaaaa_if.o aaaaaa_com_factory.o business_control_impl.o business_engine_comserver.o comserver_control.o

%.o : %.cpp
	g++ -c -g -o  $@ $<

aaaaaa_com_factory.o : aaaaaa_com_factory.h
business_control_impl.o : business_control_impl.h
business_engine_comserver.o : business_engine_comserver.h
comserver_control.o : comserver_control.h
aaaaaa_if.o : aaaaaa_if.h

clean:
	rm *.o test -f

3.14 类图

PlantUML Web Server

@startuml
class CBusinessControlInterface(产品功能控制类接口) {
}

class VBusinessInterface(具体功能点接口) {
}

class CVBusinessComServer(业务Com组件服务器类) {
static std::mutex  m_mutex;
static std::map<std::string, LPVVoid>    m_CLSID2FFMap;
}

interface VBusinessFactory(业务组件创建工厂接口){
}

class CAAAAAAComFactory(具体AAAAAA业务组件创建工厂类) {
}

class CAAAAAAInterface(AAAAAA业务com组件接口类) {
}

class CAAAAAA(AAAAAA业务组件类) {
}

class CBusinessControl(产品功能控制实现类) {
}

class CComServerControl(Com组件服务器管理) {
}

CAAAAAAComFactory --|> VBusinessFactory
CAAAAAAInterface --|> VBusinessInterface
CAAAAAA --|> CAAAAAAInterface
CBusinessControl --|> CBusinessControlInterface
CComServerControl --> CVBusinessComServer
CVBusinessComServer *-- CAAAAAAComFactory
CAAAAAAComFactory --> CAAAAAA
CComServerControl *-- VBusinessInterface
@enduml

4.调用测试

make

 ./test

可以看到,通过一些列操作后最终以一种可控的方式将业务子组件对应的函数进行了调用 

完整代码下载路径如下:

https://download.csdn.net/download/hsy12342611/87696147

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/419208.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenHarmony标准系统开机时长优化

简介 万物互联时代&#xff0c;产品性能至关重要&#xff0c;而系统启动时间是系统性能的重要组成部分&#xff0c;因为用户必须等待系统启动完成后才能使用设备。对于经常需要进行冷启动的汽车等设备而言&#xff0c;较短的启动时间至关重要&#xff08;没有人喜欢在等待几十秒…

如何手写一个文件索引工具everything(第一章)

第一章&#xff08;NTFS格式及USN日志&#xff09; 背景介绍 Windows平台的Everything文件查找速度非常快&#xff0c;优势在于利用了NTFS的USN日志&#xff0c;以及Windows上的文件监测机制我们也可以仿照类似原理&#xff0c;通过查询USN日志、监测Windows平台文件修改、使…

亚马逊卖家如何用facebook推广?

亚马逊作为全球最大的电商平台之一&#xff0c;吸引了大量的卖家和买家。对于亚马逊的卖家而言&#xff0c;如何进行有效的推广和引流成为了他们最关心的问题之一。其中&#xff0c;利用Facebook广告为亚马逊进行推广是一种较为常见的做法。 但是&#xff0c;亚马逊可以用Face…

springboot实现修改用户信息功能

目录 1、UserEntity层 2、UserMapper层 3、UserService层 4、UserController类 5、Postman测试 要实现修改用户信息的功能&#xff0c;需要编写对应的代码&#xff1a; 如&#xff1a; 在UserEntity中定义用户实体类的属性。 在UserMapper中编写修改用户的SQL语句&#…

【C++】哈希的应用 -- 布隆过滤器

文章目录一、布隆过滤器的引入二、哈希函数个数的选择三、布隆过滤器的实现四、布隆过滤器的应用五、布隆过滤器总结一、布隆过滤器的引入 我们在上一节中学习了 位图&#xff0c;知道了位图可以用来快速判断某个数据是否在一个集合中&#xff0c;但是位图有如下的缺点&#x…

Qemu虚拟机读取物理机的物理网卡的流量信息方法

项目背景&#xff1a; 比如我有三个项目 A&#xff0c;B&#xff0c;C&#xff1b;其中A项目部署在物理机上&#xff0c;B&#xff0c;C项目部署在 虚拟机V1,V2中&#xff0c;三个项目接口需要相互调用。 需要解决的问题点&#xff1a; 1&#xff0c;因为A&#xff0c;B&#x…

2016-2017 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2016)题解

2016-2017 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2016) A - Artwork 题目描述&#xff1a; 给定N*M的网格&#xff0c;给出Q次询问&#xff0c;每次询问都给出一个小矩阵&#xff0c;保证每个矩阵要么长为1&#xff0c;要么宽为1&#xff0c;将网格中矩阵部…

最近给shopify跨境电商网站搞google搜索引擎的seo优化,整理了一些内容

接到一个网站&#xff0c;首先要做一些工作&#xff0c;然后按照这个步骤做好每一步&#xff0c;网站的搜索排名会有明显的效果。 对网站进行技术审核&#xff0c;以确保它符合搜索引擎的技术要求。研究关键词并确定目标关键词。优化网站内容&#xff0c;以便更好地针对目标关…

【LeetCode】剑指 Offer 55. 二叉树的深度 p271 -- Java Version

1. 题目介绍&#xff08;55. 二叉树的深度 &#xff09; 面试题55&#xff1a;二叉树的深度&#xff0c; 一共分为两小题&#xff1a; 题目一&#xff1a;二叉树的深度题目二&#xff1a;平衡二叉树 2. 题目1&#xff1a;二叉树的深度 题目链接&#xff1a;https://leetcode.c…

简单写一个Avue增删改查

今天练习了一下avue&#xff0c;真的好用&#xff0c;个人感觉相比于用element plus的组件还方便&#xff01; 简简单单的写了一个页面的增删改查&#xff0c;思路很简单。如果在写那种后台管理项目&#xff0c;基本上全是列表页&#xff0c;用这种方法写出来第一页&#xff0c…

收入下滑,亏损扩大的人力资源管理公司罗科仕申请纳斯达克IPO上市

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;来自北京的人力资源管理公司罗科仕近期已向美国证券交易委员会&#xff08;SEC&#xff09;提交招股书&#xff0c;申请在纳斯达克IPO上市&#xff0c;股票代码为(LGCL) 。罗科仕计划通过此次纳斯…

算法训练第五十八天 | 739. 每日温度、496.下一个更大元素 I

单调栈part01739. 每日温度题目描述思路496.下一个更大元素 I题目描述思路739. 每日温度 题目链接&#xff1a;739. 每日温度 参考&#xff1a;https://programmercarl.com/0739.%E6%AF%8F%E6%97%A5%E6%B8%A9%E5%BA%A6.html 题目描述 请根据每日 气温 列表&#xff0c;重新生…

Android组件化开发

Android组件开发 一、背景 一个app随着业务增加&#xff0c;代码放在同一个模块中会越来越臃肿&#xff0c;同时也导致多人开发的一个难度。组件化可以把业务单独分出来&#xff0c;形成一个单独模块&#xff0c;可单独运行、测试等&#xff0c;相互之间不会影响。另外一个优…

鼎捷T100制造之工艺工单实战(其他工艺补充)

文章目录 一、网状工艺二、平行工艺三、替代工艺四、返工工艺五、无顺序工艺一、网状工艺 网状工艺类似一张网状结构。可以包含平行和线性工艺等于一体。 网状工艺: 产品结构 aeci004:建立作业 aecm200: 工艺路线维护

kubeasz搭建k8s集群-部署单节点集群(AllinOne部署)

1说明 kubeasz 致力于提供快速部署高可用k8s集群的工具, 同时也努力成为k8s实践、使用的参考书&#xff1b;基于二进制方式部署和利用ansible-playbook实现自动化&#xff1b;既提供一键安装脚本, 也可以根据安装指南分步执行安装各个组件。 kubeasz 从每一个单独部件组装到完…

太赫兹高速通信系统前端关键技术

摘要&#xff1a;对构成太赫兹无线系统的2 种关键电路&#xff08;分谐波混频器和二倍频器&#xff09;进行了深入研究。在关键电路研究取得突破的基础上&#xff0c;开展了太赫兹无线通信技术研究&#xff0c;构建了220 GHz 无线通信实验验证系统。220 GHz 实验验证系统在室外…

elasticsearch 其他字段类型详解和范例

本章主要内容 elasticsearch 中别名字段的详解和范例elasticsearch 中二进制类型的详解和范例elasticsearch 中的嵌套类型的详解和范例elasticsearch 中的范围类型的详解和范例elasticsearch 中的排名类型的详解和范例elasticsearch 中的ip类型的详解和范例elasticsearch 中的…

【网络应用开发】实验3——Web组件重用与JavaBeans

目录 Web组件重用与JavaBeans预习报告 一、实验目的 二、实验原理 三、实验预习内容 1. 静态include指令何时执行&#xff1f;主页面和被包含的子页面是否转换为一个转换单元&#xff1f; 2.动作指令何时执行&#xff1f;主页面和被包含的子页面是否转换为一个转换单元&a…

【Python游戏】坦克大战、推箱子小游戏怎么玩?学会这些让你秒变高高手—那些童年的游戏还记得吗?(附Pygame合集源码)

前言 下一个青年节快到了&#xff0c;想小编我也是过不了几年节日了呢&#xff01;&#xff01; 社交媒体上流传着一张照片——按照国家规定“14岁到28岁今天都应该放半天假&#xff01;”不得不说&#xff0c; 这个跨度着实有点儿大&#xff0c;如果按整自然年来算年龄&…

Spark 连接 Hive

目录 导包 修改配置文件 修改hive-site.xml文件 启动hadoop 启动hive 启动spark 测试 查看表 导包 spark连接hive需要六个关键的jar包&#xff0c;以及将hive的配置文件hive-site.xml拷贝到spark的conf目录下。如果你hive配置没问题的话&#xff0c;这些jar都在hive的目…