项目分析(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几次尝试去看,都看一半,现在终于完整的看了一下。

项目分析(PLUG),布布扣,bubuko.com

时间: 2024-11-07 14:26:28

项目分析(PLUG)的相关文章

ZOJ-1157 A Plug for UNIX 【最大流】

Problem You are in charge of setting up the press room for the inaugural meeting of the United Nations Internet eXecutive (UNIX), which has an international mandate to make the free flow of information and ideas on the Internet as cumbersome and bure

POJ 1087 A Plug for UNIX (最大流)

A Plug for UNIX Time Limit: 1000MS   Memory Limit: 65536K       Description You are in charge of setting up the press room for the inaugural meeting of the United Nations Internet eXecutive (UNIX), which has an international mandate to make the free

POJ 1087 A Plug for UNIX (网络最大流)

POJ 1087 A Plug for UNIX 链接:http://poj.org/problem?id=1087 题意:有n(1≤n≤100)个插座,每个插座用一个数字字母式字符串描述(至多有24 个字符).有m(1≤m≤100)个设备,每个设备有名称,以及它使用的插头的名称:插头的名称跟它所使用的插座的名称是一样的:设备名称是一个至多包含24 个字母数字式字符的字符串:任何两个设备的名称都不同:有k(1≤k≤100)个转换器,每个转换器能将插座转换成插头. 样例: 4 A B C D 5

POJ 1087 A Plug for UNIX(网络流之最大流)

题目地址:POJ 1087 不知道是谁把这题化为了二分最大匹配的专题里..于是也没多想就按照二分图的模型来建的(虽然当时觉得有点不大对...).后来发现二分最大匹配显然不行..有权值..直接来个最大流多方便..然后一直WA..后来仔细想了想..这根本就不能建二分图啊....这题跟二分图一点关系都没有.... 这题的建图思路是让源点与每一个设备的插座类型连边,让汇点与每一个插座连边.然后用floyd判断该设备能否通过转换转换成可以插的插座上.只要可以转换成的就连边,权值为INF.然后求一次最大流,

BNUOJ 1206 A Plug for UNIX

A Plug for UNIX Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: 108764-bit integer IO format: %lld      Java class name: Main You are in charge of setting up the press room for the inaugural meeting of the Un

POJ--1087--A Plug for UNIX【Dinic】网络最大流

链接:http://poj.org/problem?id=1087 题意:提供n种插座,每种插座只有一个,有m个设备需要使用插座,告诉你设备名称以及使用的插座类型,有k种转换器,可以把某种插座类型转为另一种,可以嵌套使用,比如有设备需使用第4种插座,现在只有第一种插座,但是有两个转换器,1→3和3→4,则通过这两个转换器设备可以充电.每种转换器有无数个.现告诉你相应信息,求至少有多少个设备无法使用插座. 网络最大流单源点单汇点,是一道基础题,图建好就能套模板了.关键是图怎么建. 还是自己设一个源

uva 753 A Plug for UNIX (最大流)

uva 753 A Plug for UNIX You are in charge of setting up the press room for the inaugural meeting of the United Nations Internet eXecutive (UNIX), which has an international mandate to make the free flow of information and ideas on the Internet as cum

POJ 1087 A Plug for UNIX(最大流dinic)

Description You are in charge of setting up the press room for the inaugural meeting of the United Nations Internet eXecutive (UNIX), which has an international mandate to make the free flow of information and ideas on the Internet as cumbersome and

项目分析(channelid是如果产生的)

channelid如何生成的 /////////////////////////////////////////////////////////////// // // I_TCPServer.h // Description: // /////////////////////////////////////////////////////////////// #pragma once #ifndef _ChannelIDGenerator_H #define _ChannelIDGenerat