在BREW中,module是基本的執(zhí)行單位,在手機(jī)上體現(xiàn)為.mod文件,在仿真器中體現(xiàn)為.dll文件。一個(gè)module可以包含一個(gè)或多個(gè)applet,或一個(gè)或多個(gè)擴(kuò)展類(關(guān)于擴(kuò)展類有多帶帶的章節(jié)進(jìn)行闡述)。凡是在手機(jī)上與其他代碼一同編譯完成的叫做靜態(tài)模塊,凡是通過(guò)下載方式(無(wú)線下載或者數(shù)據(jù)線下載)存于文件系統(tǒng)中的叫動(dòng)態(tài)模塊。

每個(gè)module都需要有標(biāo)識(shí)自身的MIF文件,從BREW 3.1開始即使是靜態(tài)module也需要有相應(yīng)的MIF。而在BREW3.1之前,對(duì)于靜態(tài)module是沒有多帶帶的MIF文件的,需要通過(guò)AEEAppInfo的結(jié)構(gòu)體來(lái)表示module的信息,里面主要包括clsid,應(yīng)用類型,圖標(biāo)等信息,每個(gè)靜態(tài) module都需要有一個(gè)實(shí)例化的AEEAppInfo結(jié)構(gòu)體,AEE從此數(shù)據(jù)結(jié)構(gòu)中獲得必要的module信息。在環(huán)境初始化(AEE_init)的時(shí)候AEE通過(guò)枚舉每個(gè)MIF文件來(lái)獲得各個(gè)module的必要信息,比如clsid等。

針對(duì)BREW3.1以前的版本,由于靜態(tài)module不存在MIF文件,所以過(guò)程有所不同。每個(gè)靜態(tài)module的實(shí)現(xiàn)必須提供一個(gè)XXX_getmodinfo(),在該函數(shù)中返回特定于該module的Mod_Load()函數(shù)指針,通常形式為 XXXMod_Load,同時(shí)返回特定于該module的AEEAppInfo結(jié)構(gòu)數(shù)據(jù)。所有的這些XXX_getmodinfo函數(shù)指針構(gòu)成了一個(gè)staticmodinfo的數(shù)組。初始化時(shí)AEE通過(guò)檢索該數(shù)組(猜測(cè)執(zhí)行其中的每一個(gè)函數(shù))來(lái)獲得每個(gè)static module的相關(guān)模塊信息(比如clsid)以及加載函數(shù)。

Module的加載是在運(yùn)行時(shí)才進(jìn)行的。對(duì)于動(dòng)態(tài)應(yīng)用,加載是通過(guò)通用函數(shù)AEEMod_Load實(shí)現(xiàn)的,而AEEMod_Load實(shí)際是調(diào)用AEEStaticMod_New,在AeeModGen.c中可以看到該函數(shù)的聲明。

int AEEStaticMod_New(int16 nSize, IShell *pIShell, void *ph, IModule **ppMod,

?????????????????? PFNMODCREATEINST pfnMC,PFNFREEMODDATA pfnMF)

{

?AEEMod *pMe = NULL;

?VTBL(IModule) *modFuncs;

if (!ppMod || !pIShell) {

??? return EFAILED;

?}

?*ppMod = NULL;?

#ifdef AEE_SIMULATOR

if (!ph) {

??? return EFAILED;

?} else {

??? g_pvtAEEStdLibEntry = (AEEHelperFuncs *)ph;

?}

#endif

?//Allocate memory for the AEEMod object

?if (nSize < sizeof(AEEMod)) {

??? nSize += sizeof(AEEMod);

?}

if (NULL == (pMe = (AEEMod *)MALLOC(nSize + sizeof(IModuleVtbl)))) {

??? return ENOMEMORY;

} ?

?modFuncs = (IModuleVtbl *)((byte *)pMe + nSize);

?

?// Initialize individual entries in the VTBL

?modFuncs->AddRef???????? = AEEMod_AddRef;

?modFuncs->Release??????? = AEEMod_Release;

?modFuncs->CreateInstance = AEEMod_CreateInstance;

modFuncs->FreeResources? = AEEMod_FreeResources;

?

?// initialize the vtable

?INIT_VTBL(pMe, IModule, *modFuncs);

?

?// initialize the data members

?

?// Store address of Modules CreateInstance function

?pMe->pfnModCrInst = pfnMC;

?

?// Store Address of Modules FreeData function

?pMe->pfnModFreeData = pfnMF;

?pMe->m_nRefs = 1;

?pMe->m_pIShell = pIShell;

?

// Set the pointer in the parameter

?*ppMod = (IModule*)pMe;

?return SUCCESS;

}

上述代碼在sdk中的AeeModGen.c可以找到,概括起來(lái),就是在為module分配內(nèi)存,并且實(shí)例化vtbl表,其中有兩行代碼值得注意:

modFuncs->CreateInstance = AEEMod_CreateInstance;

pMe->pfnModCrInst = pfnMC;

第一行是指定module的創(chuàng)建函數(shù)為AEEMod_CreateInstance,而第二行是指定該module具有自身特殊的創(chuàng)建函數(shù),該函數(shù)即為參數(shù)pfnMC指定的函數(shù)。而在AEEMod_Load中調(diào)用AEEStaticMod_New時(shí)該參數(shù)為NULL,即所有動(dòng)態(tài) module采用通用的createinstance 函數(shù)(該函數(shù)實(shí)際上即為AEEClsCreateInstance), 對(duì)于靜態(tài)module,其實(shí)其自身的XXXMod_Load加載函數(shù)和通用的AEEMod_Load具體實(shí)現(xiàn)幾乎一樣,最主要的區(qū)別在于其調(diào)用AEEStaticMod_New時(shí)指定了pfnMC參數(shù),即靜態(tài) module需要指定自身的創(chuàng)建函數(shù)。這是通過(guò)在AEEStaticMod_New中代碼modFuncs->CreateInstance = AEEMod_CreateInstance 來(lái)指定,由AEEMod_CreateInstance函數(shù)來(lái)創(chuàng)建的。

static int AEEMod_CreateInstance(IModule *pIModule,IShell *pIShell, AEECLSID ClsId, void **ppObj) {

?AEEMod??? *pme = (AEEMod *)pIModule;

?int??????? nErr = 0;

?// For a dynamic module, they must supply the AEEClsCreateInstance()

?//?? function. Hence, invoke it. For a static app, they will have

if (pme->pfnModCrInst) {

??? nErr = pme->pfnModCrInst(ClsId, pIShell, pIModule, ppObj);

#if !defined(AEE_STATIC)

?} else {

??? nErr = AEEClsCreateInstance(ClsId, pIShell, pIModule, ppObj);

#endif

?return nErr;

}

對(duì)于動(dòng)態(tài) module,由于pme->pfnModCrInst為NULL,所以調(diào)用通用的創(chuàng)建函數(shù)AEEClsCreateInstance(ClsId, pIShell, pIModule, ppObj)來(lái)進(jìn)行創(chuàng)建。AEEClsCreatelnstance通過(guò)調(diào)用AEEAppGen.c的AEEApplet_New()方法來(lái)完成空間分配、虛函數(shù)表構(gòu)造、初始化等一系列工作。而對(duì)于靜態(tài)module,因?yàn)橹付俗陨淼膭?chuàng)建函數(shù),所以pme->pfnModCrInst不為NULL,從而執(zhí)行特定于該module自身的創(chuàng)建函數(shù)

不論是 AEEClsCreateInstance還是pme->pfnModCrInst其實(shí)都是類似的,通過(guò)AEEApplet_New(除extension 外通常都是調(diào)用該函數(shù))來(lái)最終創(chuàng)建應(yīng)用,AEEApplet_New無(wú)非是具體分配applet內(nèi)存,初始化applet的vtbl(這里最重要的是實(shí)例化applet_handleevent)并返回Iapplet指針,供運(yùn)行時(shí)使用 。