Brew中的Module的实现方法

Brew中的Module的实现方法:
【原创作者:shosh, http://www.yuleyx.com/shosh
 
我们从AEEModGen.c中提供的用于创建Module对象的对外接口入手,函数如下:
01 int AEEStaticMod_New (int16 nSize , IShell  *pIShell ,  void  *ph , IModule  * *ppMod ,
02                     PFNMODCreateINST pfnMC ,PFNFREEMODDATA pfnMF )
03 {
04   AEEMod  *pMe  = NULL ;
05   VTBL (IModule )  *modFuncs ;
           ……………省略第6到73行的代码…………………
74 }
第4行申请AEEMod结构体类型的pMe指针,该结构体的定义如下:
01 //Structure that implements the IModule interface
02
typedef  struct _AEEMod                                     
03 {
04        DECLARE_VTBL (IModule )    // Virtual Table with pointers to IModule functions
05
        
06        uint32        m_nRefs ;                  // Reference count for this module
07
        IShell  *       m_pIShell ;               // Pointer to IShell
08

09         //Address of CreateInstance function of the module. This is needed for
10
         // static modules
11
        PFNMODCreateINST        pfnModCrInst ; 
12
13         //Address of the function to free the module data. This is needed for static
14
         // modules that define their own data.
15
        PFNFREEMODDATA          pfnModFreeData ;
16
17 } AEEMod ;
在该结构体的第4行,声明了一个Virtual Table(虚拟表:专门用来来存放函数指针的结构体,不过此处是指向该结构体的指针),这个是重点,待会将展开来讲。第6行的m_nRefs是模仿COM中的计数器,第11行和第15行的两个函数指针成员,其中pfnModCrInst是用来存放创建Module本身的函数(地址),而pfnModFreeData是Module自身提供释放自身数据的函数指针。
下面我们将结构体中的第四行DECLARE_VTBL (IModule )展开:
先来看看DECLARE_VTBL的定义:
1 // Use as first member of classes that override QINTERFACE()
2
#define DECLARE_VTBL (iname )      iname   vt##iname ;
所以DECLARE_VTBL (IModule )就是: IModule vtIModule;
IModule是一个结构体类型,定义如下:
1 typedef  struct _IModule         IModule ;
所以,我们需要了解_IModule的结构体是什么样子的。我们需要从下面的四行代码入手,不过下面主要是两个宏定义,需要展开才能够明白它们到底是什么东西。
1QINTERFACE (IModule )
2 {
3   INHERIT_IModule (IModule ) ;
4 } ;
下面是所有相关的宏定义,先贴出来,然后再用这些定义将上面的4行慢慢展开:
01 typedef  struct _IModule         IModule ;
02 #define INHERIT_IModule (iname ) \
03   INHERIT_IBase (iname ) ; \
04    int          ( *CreateInstance ) (iname  * po ,IShell  * pIShell ,AEECLSID ClsId , void  * * ppObj ) ; \
05    void         ( *FreeResources ) (iname  * po , IHeap  * ph , IFileMgr  * pfm )
06
07QINTERFACE (IModule )
08 {
09   INHERIT_IModule (IModule ) ;
10 } ;
11 #define IMODULE_AddRef (p )                    GET_PVTBL (p ,IModule ) - >AddRef (p )
12 #define IMODULE_Release (p )                   GET_PVTBL (p ,IModule ) - >Release (p )
13 #define IMODULE_CreateInstance (p ,ps ,id ,ppo )  GET_PVTBL (p ,IModule ) - >CreateInstance (p ,ps ,id ,ppo )
14 #define IMODULE_FreeResources (p ,ph ,pfm )      GET_PVTBL (p ,IModule ) - >FreeResources (p ,ph ,pfm )
15
16 #define QINTERFACE (iname )  struct _##iname  {\
17                              struct VTBL (iname )   *pvt ;\
18                            } ;\
19                            typedef  struct VTBL (iname ) VTBL (iname ) ;\
20                            struct VTBL (iname )
21
22 #define VTBL (iname )       iname##Vtbl
23
24 #define INHERIT_IBase (iname ) \
25  uint32   ( *AddRef )          (iname * ) ;\
26  uint32   ( *Release )         (iname * )
先将QINTERFACE (IModule )展开,根据上面第16到20行的定义以及第22行VTBL的定义,得到:
1 struct _IModule  {
2         struct IModuleVtbl  *pvt ;
3         } ;
4         typedef  struct IModuleVtbl IModuleVtbl ;
5         struct IModuleVtbl
再将INHERIT_IModule (IModule ) ;展开,根据上面第2到5行的定义以及第24到26行INHERIT_IBase的定义,得到:
1   uint32   ( *AddRef )          (IModule * ) ;
2   uint32   ( *Release )         (IModule * ) ;
3    int          ( *CreateInstance ) (IModule  * po ,IShell  * pIShell ,AEECLSID ClsId , void  * * ppObj ) ;
4    void         ( *FreeResources ) (IModule  * po , IHeap  * ph , IFileMgr  * pfm ) ;
将以上结果合并起来,就可以得到如下代码:
01 struct _IModule
02 {
03         struct IModuleVtbl  *pvt ;
04 } ;
05 typedef  struct IModuleVtbl IModuleVtbl ;
06 struct IModuleVtbl
07 {
08        uint32   ( *AddRef )          (IModule * ) ;
09        uint32   ( *Release )         (IModule * ) ;
10         int   ( *CreateInstance ) (IModule  * po ,IShell  * pIShell ,AEECLSID ClsId , void  * * ppObj ) ;
11         void  ( *FreeResources ) (IModule  * po , IHeap  * ph , IFileMgr  * pfm ) ;
12 } ;
好,现在来总结一下:
前面已经说到DECLARE_VTBL (IModule )就是: IModule vtIModule;,它作为AEEMod结构体的第一个成员。IModule是_IModule的结构体类型,_IModule结构体只有一个成员,就是结构体IModuleVtbl的指针。而IModuleVtbl指向的是虚拟函数表的首地址,所以如果有一个IModule* p的指针,p->pvt就是IModuleVtbl*的类型,再用p->pvt->functionName找到对应的函数。为了方便,虚拟函数表中函数的调用是使用宏来定义的,从结构体IModuleVtbl中我们可以看到Module提供了四种方法,宏定义如下,其中还用到GET_PVTBL宏定义:
1 #define IMODULE_AddRef (p )                    GET_PVTBL (p ,IModule ) - >AddRef (p )
2 #define IMODULE_Release (p )                   GET_PVTBL (p ,IModule ) - >Release (p )
3 #define IMODULE_CreateInstance (p ,ps ,id ,ppo )  GET_PVTBL (p ,IModule ) - >CreateInstance (p ,ps ,id ,ppo )
4 #define IMODULE_FreeResources (p ,ph ,pfm )      GET_PVTBL (p ,IModule ) - >FreeResources (p ,ph ,pfm )
5 #define GET_PVTBL (p ,iname )        ( (iname * )p ) - >pvt
我们以AddRef函数为例,我们调用的时候会使用"IMODULE_AddRef(p);"语句,将其展开,其实就是:
((IModule * )p ) - >pvt - >AddRef (p ) ;
这样就实现了虚拟函数表中函数的调用了。
 
下面再回到用于创建Module对象的对外接口AEEStaticMod_New,具体代码如下:
01 int AEEStaticMod_New (int16 nSize , IShell  *pIShell ,  void  *ph , IModule  * *ppMod ,
02                     PFNMODCreateINST pfnMC ,PFNFREEMODDATA pfnMF )
03 {
04   AEEMod  *pMe  = NULL ;
05   VTBL (IModule )  *modFuncs ;     //将其展开就是 IModuleVtbl *modFuncs;
06

07    if  ( !ppMod  | |  !pIShell )  {
08       return EFAILED ;
09    }
10
11    if  (nSize  <  0 )  {
12       return EBADPARM ;
13    }
14    *ppMod  = NULL ;
15  
16 #ifdef AEE_SIMULATOR
17    // IMPORTANT NOTE: g_pvtAEEStdLibEntry global variable is defined for 
18
    //   SDK ONLY! This variable should NOT BE:
19
    //
20
    //      (1) overwritten 
21
    //      (2) USED DIRECTLY by BREW SDK users. 
22
    //
23
    //  g_pvtAEEStdLibEntry is used as an entry point to AEEStdLib,
24
    //   DO NOT REMOVE the next five lines.
25
    if  ( !ph )  {
26       return EFAILED ;
27    }  else  {
28      g_pvtAEEStdLibEntry  =  (AEEHelperFuncs  * )ph ;
29    }
30 #endif
31
32    //Allocate memory for the AEEMod object
33

34    if  (nSize  <  sizeof (AEEMod ) )  {
35      nSize  + =  sizeof (AEEMod ) ;
36    }
37
38    if  (NULL  = =  (pMe  =  (AEEMod  * )MALLOC (nSize  +  sizeof (IModuleVtbl ) ) ) )  {
39       return ENOMEMORY ;
40    }
41  
42    // Allocate the vtbl and initialize it. Note that the modules and apps 
43
    // must not have any static data. Hence, we need to allocate the vtbl as 
44
    // well.
45

46   modFuncs  =  (IModuleVtbl  * ) ( (byte  * )pMe  + nSize ) ;
47
48    // Initialize individual entries in the VTBL
49
   modFuncs - >AddRef          = AEEMod_AddRef ;
50   modFuncs - >Release         = AEEMod_Release ;
51   modFuncs - >CreateInstance  = AEEMod_CreateInstance ;
52   modFuncs - >FreeResources   = AEEMod_FreeResources ;
53
54
55    // initialize the vtable
56
   INIT_VTBL (pMe , IModule ,  *modFunc
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值