WAP之家:为您提供最全最新的WAP技术,CP.SP.3G等行业资讯。 WAP之家交流论坛全新开放 点击进入>>
WAP资讯 | 3G动态 | SP动态 | 运营商动态 | 内容商动态 | 制造商动态 | 论坛讨论>> 每次自动访问
WAP技术 | WAP源码 | 手机编程 | 手机源码 | 无线技术 | J2ME技术 | 手机软件 添加到收藏夹
IVR技术 | SP资料 | SMS MMS技术 | 商业方案 | IVR下载 | 书籍教程 | 工具软件 语言:繁體中文

WAP之家技术文章手机编程BREW深入BREW模块加载机制

深入BREW模块加载机制
作者:东方欲晓  来源:本站整理  发布时间:2008-4-8 1:02:34

在BREW中,module是基本的执行单位,一个module可以包含一个或多个applet,或者多个extension class。按照module处于code space(即OEM出厂时已经将module编译进image中了)还是通过下载方式(无线下载或者数据线下载)存于文件系统可以分为static和dynamic,主要包括:dynamic module(applet),static module(applet)和dynamic extension class(module)。本文将详细阐述static和dynamic module的加载过程。由于完整的module加载过程高通没有文档公开,所以以下内容是结合我阅读的相关文档以及我的日常工作而写,是我对模块加载的理解,可能有不当之处,还请指教。
1. Module的信息
MIF文件,这个大家都知道了。原则上来说,每个module都需要有标识自身的MIF文件,从BREW 3.1开始已经强制如此了,static module也需要有相应的MIF。而在BREW3.1之前,对于static module是没有单独的MIF文件的,但有一个AEEAppInfo的结构体来表示module的信息,里面主要包括clsid,app type等信息,每个static module都需要有一个实例化的AEEAppInfo结构体,BREW从此结构中获得必要的module信息。
2. 枚举Module信息
这一步是在BREW环境初始化的时候进行的(猜测是在AEE_init中),由于通常在开机时就初始化BREW环境,所以枚举Module信息通过在一开机就进行(进行程序跟踪结果也证实如此)。对于dynamic module,BREW通过检索各个MIF文件来获得各个module的必要信息,比如clsid等。而对于static module,由于不存在MIF文件,所以过程有所不同。每个static module的实现必须提供一个XXX_getmodinfo(),在该函数中返回特定于该module的Mod_Load()函数指针,通常形式为 XXXMod_Load,同时返回特定于该module的AEEAppInfo结构数据。所有的这些XXX_getmodinfo函数指针构成了一个staticmodinfo的数组。BREW初始化时通过检索该数组(猜测执行其中的每一个函数)来获得每个static module的相关模块信息(比如clsid)以及加载函数(我们知道,对于dynamic module, load的函数是通用的AEEMod_Load,所以应用无需再提供自己的Load函数,而static module必须提供自己的Mod_Load 函数)
3. Module加载
Module的加载是在运行时才进行的,即执行该Module的时候。对于dynamic module,加载是通过通用函数AEEMod_Load实现的,而AEEMod_Load实际是调用AEEStaticMod_New,该函数的原型为int AEEStaticMod_New(int16 nSize, IShell *pIShell, void *ph, IModule **ppMod,                     PFNMODCREATEINST pfnMC,PFNFREEMODDATA pfnMF),大家在AeeModGen.c中可以看到。需要说明的是,AEEMod_Load中调用该函数时,倒数第二个参数为NULL,这说明什么?我们来看看AEEStaticMod_New具体作些什么,

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
  // IMPORTANT NOTE: g_pvtAEEStdLibEntry global variable is defined for
  //   SDK ONLY! This variable should NOT BE:
  //
  //      (1) overwritten
  //      (2) USED DIRECTLY by BREW SDK users.
  //
  //  g_pvtAEEStdLibEntry is used as an entry point to AEEStdLib,
  //   DO NOT REMOVE the next five lines.
  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;
  }
 
  // Allocate the vtbl and initialize it. Note that the modules and apps
  // must not have any static data. Hence, we need to allocate the vtbl as
  // well.

  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 Module's CreateInstance function
  pMe->pfnModCrInst = pfnMC;

  // Store Address of Module's 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可以找到,概括起来,就是在为module分配内存,并且实例化vtbl表,其中有两行代码值得注意:
modFuncs->CreateInstance = AEEMod_CreateInstance;
pMe->pfnModCrInst = pfnMC;

第一行是指定module的创建函数为AEEMod_CreateInstance,而第二行是指定该module具有自身特殊的创建函数,该函数即为参数pfnMC指定的函数。而在AEEMod_Load中调用AEEStaticMod_New时该参数为NULL,即所有dynamic module采用通用的createinstance 函数(该函数实际上即为AEEClsCreateInstance)
大家或许已经猜到了,对于static module,其实其自身的XXXMod_Load加载函数和通用的AEEMod_Load具体实现几乎一样,最主要的区别在于其调用AEEStaticMod_New时指定了pfnMC参数,即static module需要指定自身的createinstance函数。
4. Module 创建
这是通过 在AEEStaticMod_New中代码
modFuncs->CreateInstance = AEEMod_CreateInstance;指定的
AEEMod_CreateInstance函数来创建的。我们来看一下AEEMod_CreateInstance的庐山真面目:
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 sup

[1] [2]  下一页

[] [返回上一页] [打 印]
文章评论

用户名: 查看更多评论

分 值:100分 85分 70分 55分 40分 25分 10分 0分

内 容:

         (注“”为必填内容。) 验证码: 验证码,看不清楚?请点击刷新验证码