浅谈X3架构

之所以命名为浅谈,是因为对作者的构思还不是很清楚,有许多的内容理解不透彻,所以先简单的谈一下

1  x3架构中关于各个ID的理解

X3CLSID  

提起这个,就不得不说一下,宏的应用

#define X3CLSID_DEFINE(clsid, str)  \

namespace x3 { static const X3CLSID clsid(str); }  \
    typedef int dumy_ ## clsid

其应用场景如下:X3CLSID_DEFINE(CLSID_StringTable, "b8c36b29-59c3-4db2-be43-fd4982e6e71d");

是在每个模块定义的开头,调用, Cx_Interface<Ix_StringTable> pIFTable(x3::CLSID_StringTable);将本地

在宏调用中,第一个传入参数定义了全局变量,第二个参数定义了模块的CLSID,引用调用的话,就可以用第一个参量进行

引用调用,不得不说,这个宏还是挺通用的


X3IID

#define X3DEFINE_IID(_Interface) \
    virtual ~_Interface() {}     \
     static X3IID GetIID() { static X3IID id = x3::hashkey(#_Interface); return id; }

其应用场景:X3DEFINE_IID(Ix_StringTable)

在每个模块内部,定义了一个静态常量,以便之后引用,但是应用上倒没有学会怎么用了


X3CLASSENTRY

这个结构是创建模块以及管理模块单一对象,其中存储了关于模块的引用信息以及属性

//! class factory function.
typedef Ix_Object* (*PFNXObjectCreator)(X3IID, HMODULE);



//! object count of a class.
typedef long (*PFNXGetObjectCount)();


//! object (used by other modules) count of a class.
typedef long (*PFNXRefCountByOthers)();

定义了模块的创建函数,此函数通过模块内部的X3IID,找到模块名和句柄,并创建或者说是加载


返回了本模块的引用计数

返回了本模块被其他模块引用的计数


class X3CLASSENTRY
{
public:
    BYTE                type;               //!< see MIN_SINGLETON_TYPE and XModuleMacro.h
    const char*         className;          //!< implement class name
    X3CLSID             clsid;              //!< class id
    PFNXObjectCreator   pfnObjectCreator;   //!< class factory function
    PFNXGetObjectCount  pfnGetObjectCount;  //!< object count of this class
    PFNXRefCountByOthers    pfnRefCountByOthers;    //!< count of objects used by other modules


    //! Used by XDEFINE_CLASSMAP_ENTRY, XDEFINE_CLASSMAP_ENTRY_Singleton
    X3CLASSENTRY(BYTE           _type,
        const char*             _className,
        const X3CLSID&          _clsid,
        PFNXObjectCreator       _pfnObjectCreator,
        PFNXGetObjectCount      _pfnGetObjectCount = NULL,
        PFNXRefCountByOthers    _pfnRefCountByOthers = NULL)


        : type(_type), className(_className), clsid(_clsid)
        , pfnObjectCreator(_pfnObjectCreator)
        , pfnGetObjectCount(_pfnGetObjectCount)
        , pfnRefCountByOthers(_pfnRefCountByOthers)
    {
    }


    //! Used by XEND_DEFINE_MODULE
    X3CLASSENTRY()
        : type(0), className(""), clsid("")
        , pfnObjectCreator(NULL), pfnGetObjectCount(NULL)
        , pfnRefCountByOthers(NULL)
    {
    }


    //! class factory registries. filled by XBEGIN_DEFINE_MODULE.
    static const X3CLASSENTRY s_classes[];
};

//! Begin group of class factory registry.
/*!
    \ingroup _GROUP_PLUGIN_CORE_
    \see XEND_DEFINE_MODULE
    \see XEND_DEFINE_MODULE_DLL, XEND_DEFINE_MODULE_MFCEXTDLL
*/
#define XBEGIN_DEFINE_MODULE()  \
    const X3CLASSENTRY X3CLASSENTRY::s_classes[] = {


//! Register a regular class.
/*!
    \ingroup _GROUP_PLUGIN_CORE_
    \param clsid class unique id, X3CLSID constant.
    \param cls implement class
*/
#define XDEFINE_CLASSMAP_ENTRY(clsid, cls)      \
    X3CLASSENTRY(1, "Cx_Object<" #cls ">", clsid,  \
        reinterpret_cast<PFNXObjectCreator>(&Cx_Object<cls>::CreateObject), \
        reinterpret_cast<PFNXGetObjectCount>(&Cx_Object<cls>::GetObjectCount),  \
        reinterpret_cast<PFNXRefCountByOthers>(&Cx_Object<cls>::GetRefCountByOthers)),


//! Register a single instance class.
/*!
    \ingroup _GROUP_PLUGIN_CORE_
    \param clsid class unique id, X3CLSID constant.
    \param cls implement class
*/
#define XDEFINE_CLASSMAP_ENTRY_Singleton(clsid, cls)    \
    X3CLASSENTRY(MIN_SINGLETON_TYPE,   \
        "Cx_SingletonObject<" #cls ">", clsid,  \
        reinterpret_cast<PFNXObjectCreator>(&Cx_SingletonObject<cls>::CreateObject),    \
        reinterpret_cast<PFNXGetObjectCount>(&Cx_SingletonObject<cls>::GetObjectCount), \
        reinterpret_cast<PFNXRefCountByOthers>(&Cx_SingletonObject<cls>::GetRefCountByOthers)),


//! End group of class factory registry.
/*!
    \ingroup _GROUP_PLUGIN_CORE_
    \see XEND_DEFINE_MODULE_DLL, XEND_DEFINE_MODULE_MFCEXTDLL
*/
#define XEND_DEFINE_MODULE() \
        X3CLASSENTRY() \
    };

XDEFINE_CLASSMAP_ENTRY_Singleton(x3::CLSID_StringTable, Cx_StringTable)

这个结构的应用一般在模块定义接口实现文件中,此宏通过Cx_Object的模版类,后延到ClsType以及模块定义类的宏定义

的函数中。其中Creator函数就是询问子类实现中,是否由此接口模块,并实现了此接口。另外两个接口分别返回的是程序中

有多少这个接口对象以及被其他引用的计数是多少。

XDEFINE_CLASSMAP_ENTRY_Singleton(x3::CLSID_ConfigDBFactory, Cx_ConfigFactory)

或者定义的静态对象实例,需要用到Cx_ModuleItem对此实例进行管理。


除了在模块实现文件Module.cpp中定义了全局的一些结构外,还在XClassMacro中定义了每个实现的接口函数

//! Begin definition group of how many interfaces supported by the class.
/*!
    \ingroup _GROUP_PLUGIN_CORE_
    \param cls class name.
    \see X3END_CLASS_DECLARE, X3DEFINE_INTERFACE_ENTRY, X3USE_INTERFACE_ENTRY
    \code
    class Cx_Example : public Cx_Base, public Ix_Example
    {
        X3BEGIN_CLASS_DECLARE(Cx_Example)
            X3DEFINE_INTERFACE_ENTRY(Ix_Example)
            X3USE_INTERFACE_ENTRY(Cx_Base)
        X3END_CLASS_DECLARE()
    protected:
        Cx_Example();
        virtual ~Cx_Example();
    private:
        virtual void foo();
    };
    \endcode
*/
#define X3BEGIN_CLASS_DECLARE(cls)  \
public: \
    const char* DoGetClassName() const { return #cls; }    \
    static bool DoQueryInterface(cls* self, X3IID iid, Ix_Object** ppv, HMODULE fromdll)  \
    {


//! Indicate a interface is supported by the class.
/*!
    \ingroup _GROUP_PLUGIN_CORE_
    \param _Interface interface name.
    \see X3BEGIN_CLASS_DECLARE, X3USE_INTERFACE_ENTRY
*/
#define X3DEFINE_INTERFACE_ENTRY(_Interface)    \
        if (iid == _Interface::GetIID())        \
        {   \
            *ppv = static_cast<Ix_Object*>(static_cast<_Interface*>(self)); \
            (*ppv)->InterfaceAddRef(fromdll);            \
            return true;    \
        }


//! Indicate this class is derived from a implement class.
/*! All interfaces of the base class are supported by this class.
    \ingroup _GROUP_PLUGIN_CORE_
    \param _BaseClass base class that has the group declared using X3BEGIN_CLASS_DECLARE.
    \see X3BEGIN_CLASS_DECLARE, X3DEFINE_INTERFACE_ENTRY
*/
#define X3USE_INTERFACE_ENTRY(_BaseClass)       \
        if (_BaseClass::DoQueryInterface(self, iid, ppv, fromdll))  \
        {   \
            return true;    \
        }


//! End group of class definition.
/*!
    \see X3BEGIN_CLASS_DECLARE, X3DEFINE_INTERFACE_ENTRY
*/
#define X3END_CLASS_DECLARE() \
        return false; \
    }


 X3BEGIN_CLASS_DECLARE(Cx_StringTable)
        X3DEFINE_INTERFACE_ENTRY(Ix_StringTable)
    X3END_CLASS_DECLARE()

这些宏用于每个实现接口的文件中,用于定义之前宏用到的一些查询函数,以及父类接口的查询。


Cx_ObjectFactory

这个是管理各个子模块的管理类了,相当于企业ceo,实现了两个接口以及模块加载一系列函数。

其接口包括了 virtual bool IsCreatorRegister(const X3CLSID& clsid);
        virtual int CreateObject(const X3CLSID& clsid, X3IID iid, Ix_Object** ppv, HMODULE fromdll);

其余均是模块内部定义的自使用函数。

其结构包括了 vector<X3CLSID> CLSIDS;

std::pair<X3ClassEntry,long> MAPITEM;

hash_map<std::string,MAPITEM> CLSMAP;

每个模块中可能含有若干个接口,所以定义了模块结构

struct MODULE                       //!< plugin module info
    {
        HMODULE             hdll;       //!< DLL handle of the plugin
        Ix_Module*          module;     //!< plugin module object
        CLSIDS              clsids;     //!< all classes of the plugin
        bool                owned;      //!< the DLL is loaded by this class or not
        bool                inited;     //!< InitializePlugins() has been called or not
        wchar_t             filename[MAX_PATH];   //!< plugin filename


        MODULE() : hdll(NULL), module(NULL), owned(false), inited(false) {}
    };


然后本对象所含的主要对象已经昭然若揭了

std::vector<MODULE *>  m_modules;

CLSMAP                             m_clsmap;

long                                     m_unloading;

long                                     m_loading;


应用的主要目的就是管理这些模块,外部模块,首先将之加载进去LoadLibrary,定位GetProcAddress其x3InitializePlugin,如果可以

获得本模块的函数导出,那么就说明此模块已经被加载,此时直接卸载掉,否则就获取DllGetClassObject进行加载


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值