用户: 密码: 答案:   我要注册   忘记密码

加入收藏  设为首页

开发文档

CNJM首页

业界新闻

手机软件

终端应用

资源下载

EclipseME

CNJM论坛

                 

频道列表

J2ME开发 176篇
服务器端开发 33篇
JAVA语言 71篇
游戏与图形 101篇
WindowsMobile开发 6篇
Symbian开发 61篇
Brew开发 36篇
其它开发平台 6篇

热点文章

BREW™ SDK入门篇...  8247次
BREW开发相关技术论坛 7329次
BREW究竟是什么-B... 7271次
[原创]BREW高手之...  7213次
BREW & J2ME:在差...  7142次
BREW™ SDK入门篇...  6795次
深入Brew编程之一...  6760次
深入BREW消息处理机制 6312次
深入BREW模块加载机制 6185次
BREW SDK入门 6076次
联通博路的开发商F... 5793次
[原创] brew下的大... 5378次

文章搜索

搜 索
按 照
频 道
  
深入BREW模块加载机制
编辑:rocks    审核:rocks    文章来源:歪酷博客
关键词:无    发表日期:2006-02-09 15:47:19    浏览次数:6186次
本文版权归原作者,中国JAVA手机网收录本文的目的是让更多人阅读到此文章。转载请注明出处为中国JAVA手机网<www.cnjm.net>
来自:http://www.cnjm.net/tech/article846.html

[转载于歪酷博客]
原文:http://nicefuture.yculblog.com/post.722858.html
深入BREW模块加载机制
东方欲晓 @ 2005-06-13 20:52

深入BREW模块加载机制
作者:东方欲晓
2005-6-13
MSN:mynicefuture@hotmail.com
Email: mynicefuture@126.com
转载请注明出处
JAVA手机网[www.cnjm.net]
在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加载过程高通没有文档公开,所以以下内容是结合我阅读的相关文档以及我的日常工作而写,是我对模块加载的理解,可能有不当之处,还请指教。
JAVA手机网[www.cnjm.net]
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;
JAVA手机网[www.cnjm.net]
 }

 *ppMod = NULL;
 
#ifdef AEE_SIMULATOR
 // IMPORTANT NOTE: g_pvtAEEStdLibEntry global variable is defined for
JAVA手机网[www.cnjm.net]
 //   SDK ONLY! This variable should NOT BE:
 //
 //      (1) overwritten
 //      (2) USED DIRECTLY by BREW SDK users.
 //
JAVA手机网[www.cnjm.net]
 //  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;
 }
JAVA手机网[www.cnjm.net]
#endif

JAVA手机网[www.cnjm.net]
 //Allocate memory for the AEEMod object

 if (nSize < sizeof(AEEMod)) {
    nSize += sizeof(AEEMod);
JAVA手机网[www.cnjm.net]
 }
JAVA手机网[www.cnjm.net]

 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
JAVA手机网[www.cnjm.net]
 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 supply the AEEClsCreateInstance()
 //   function. Hence, invoke it. For a static app, they will have
 //   registered the create Instance function. Invoke it.
 if (pme->pfnModCrInst) {
    nErr = pme->pfnModCrInst(ClsId, pIShell, pIModule, ppObj);
#if !defined(AEE_STATIC)
 } else {
JAVA手机网[www.cnjm.net]
    nErr = AEEClsCreateInstance(ClsId, pIShell, pIModule, ppObj);
#endif
 }

 return nErr;
}

可见对于dynamic module,由于pme->pfnModCrInst为NULL,所以调用通用的创建函数AEEClsCreateInstance(ClsId, pIShell, pIModule, ppObj)来进行创建。而对于static module,因为指定了自身的Createinstance函数,所以pme->pfnModCrInst不为NULL,从而执行特定于该module自身的createinstance函数
5. Applet创建
JAVA手机网[www.cnjm.net]
之后,不管是 AEEClsCreateInstance还是pme->pfnModCrInst其实都是类似的,通过AEEApplet_New(除extension class外通常都是调用该函数)来最终创建applet,AEEApplet_New无非是具体分配applet内存,初始化applet的vtbl(这里最重要的是实例化applet_handleevent)并返回Iapplet指针,供运行时使用
JAVA手机网[www.cnjm.net]
6. 程序运行
通常就是在applet_handleevent中进行各种事件处理。处理前一般将传入的Iapplet指针先转换为AEEApplet或者用户自身的结构,以便可以访问其中的数据变量。

以上就是我对BREW模块加载机制的理解。大家相互交流
来自:http://www.cnjm.net/tech/article846.html

相关文章
   暂无相关文章
最新评论
网站简介  |  关于版权  |  广告服务  |  网站地图  |  联系我们
Copyright © www.CNJM.net, All rights reserved
中国JAVA手机网 版权所有
ICP备案:京ICP备041452