• 项目分析(PLUG)


    plug过程
    1.INIT_PLUG
    #define INIT_PLUG Plug::InitPlug g_InitPlug(true);
    //共享内存数据结构
    struct PlugShareMemory
    {
        void*    pFirstHand;    //第一个打开文件的句柄
        I_PlugModuleManage*    pBuffer;    //共享内存
    };
    
    inline void CreateShareMemory(I_PlugModuleManage* pmm)
    {
        char id_name[64] = {0};
        GetShareMemoryName(id_name);
        void* MemHand = PlugCreateFileMapping(id_name, 8);
        if (!MemHand)
            return ;
        void* pBuf = PlugMapViewOfFile(MemHand);//映射文件映射到进程空间中,pBuf就是映射之后的指针
        //第一次打开, 保存数据
        PlugShareMemory* psm = new PlugShareMemory;
        memcpy(pBuf, &psm, sizeof(psm));//将psm的指针的值复制到映射地址中去,看出共享的就是psm的指针的值
        PlugUnMapViewOfFile(pBuf);
        psm->pFirstHand = MemHand;//保存映射文件的句柄
        psm->pBuffer = pmm;//将pmm的值复制到共享内存中,由pmm就可以操作共享内存了,设计还是很巧妙的
    }
    
    inline bool __stdcall DllLoadContorl::LoadDll(std::wstring filename)//总共会加载三个目录下的DLL
    {
        void* hInst = xLoadLibraryW((wchar_t*)filename.c_str());//加载目录下的dll,返回对应DLL的指针
        if(hInst == NULL)
        {
            std::wstring mess = L"Can't load the dll file: ";
            mess += filename;
            PlugMessageBox(mess.c_str());
            return false;
        }
        //保持它在内存中,此类退出时自动释放
        m_ahDllHandle[m_dwDllCount] = hInst;//将DLL保存在m_ahDllHandle中
        ++m_dwDllCount;
        return true;
    }
    
    在调用return LoadLibraryW(lpLibFileName);会自动调用PLUG_COMPONENT_AUTO_REG具体为什么会自动调用我也不明白
    PLUG_COMPONENT_AUTO_REG(Demo)//DO NOT EDIT THIS
    #define PLUG_COMPONENT_AUTO_REG(ProjectName) 
        I_##ProjectName* __stdcall New##ProjectName()
    {
        return new ProjectName();
    }
        void __stdcall Delete##ProjectName(void* p)
    {
        ProjectName* pp = static_cast<ProjectName*>((I_##ProjectName*)p);
        delete pp;
    }
    Plug::AutoReg ProjectName##AutoReg(#ProjectName, (void*)New##ProjectName, (void*)Delete##ProjectName);
        void __stdcall Reg##ProjectName()
    {
        ProjectName##AutoReg;
    }
    看这个宏定义了创建实例和删除实例的函数指针,然后调用AutoReg
    inline void __stdcall PlugModuleManage::push(const char* id, void* pNewInstance, void* pDeleteInstance)
    {
    #ifdef _DEBUG
        find_overlap(id);//如果是debug版就检测有同有重复组件
    #endif
        if(id)
        {
            PlugModule module;
            module.id = id;//ID即名字
            module.pNewInstance = pNewInstance;//新建实例函数
            module.pDeleteInstance = pDeleteInstance;//删除实例函数
            m_modules.push_back(module);//将实例信息保存到m_modules中
            //std::sort(m_modules.begin(), m_modules.end());
        }
    }
    Plug::SetApp(new AppEx());//保存一个APP的值,具体什么用,我也不太明白
    
    2.NEW
    #define NEW(ProjectName) (struct I_##ProjectName*)(Plug::PlugCreeateInstance(#ProjectName))
    根据ProjectName在保存模块的容器中查找
    try
    {
        CreateInstanceFun cifun = (CreateInstanceFun)(pNewInstance);
        void* pInstance        = (void*)cifun();//调用创建实例函数即调用构造函数
        pmm->AddInstance(pInstance, pDeleteInstance);//根据指针作为KEY保存实例m_instances中m_instances[*(int*)&p] = instance;
        return pInstance;//返回实例的指针,相当于返回new出来的指针
    }
    3.DEL
    #define DEL(instance) Plug::PlugDeleteInstance(instance)
    同样在m_instances中根据实例指针查找,找到指针删掉
    fun(p);//调用实例的删除函数,即调用实例的析构函数所以在这个函数里可能还会调释放组件,这时一定把锁放开???
    上面一个简单的PLUG的工作流程

    这个PLUG几次尝试去看,都看一半,现在终于完整的看了一下。

  • 相关阅读:
    LAMP环境搭建
    Centos系统下Lamp环境的快速搭建(超详细)
    主题:Windows系统服务器磁盘挂载
    云硬盘
    独立IP与共享IP的区别
    网站备案的注意事项
    云主机与vps虚拟主机的区别
    vim 命令大全 / vi 命令大全
    【Linux】Linux中常用操作命令
    Linux Shell常用技巧(一) RE
  • 原文地址:https://www.cnblogs.com/zzyoucan/p/3893430.html
Copyright © 2020-2023  润新知