BREW? SDK入门篇(二)
第二部分 – 在模拟器上运行“Hello BREW”
在跟随本文学习相关知识点之前,你需要以下环境:
1. Microsoft Visual C++ 6.0®(或更高版本)
2. 1.1版的BREW SDK.
要了解系统最低要求,和获得更细节的资料,SDK的安装指导,请查看SDK 1.1的README文件。注意,在这里我假设你已经读过了本系列中之前的一篇文章,“什么是BREW”以及本系列的前一篇文章“第一部分-预备知识”。我进一步假设你已经创建了一个模块信息文件(helloBREW.mif)和一个BREWx小程序资源文件(helloBREW.bar)并且分别将他们拷贝到了“...yourBREWdir\Examples\mif\256Color\”和“...yourBREWdir\Examples\en\256Color\”两个目录。同时,在“...yourBREWdir\Examples\helloBREW\”目录必须有用BREW资源编辑器生成的helloBREW_res.h文件,用BREW应用程序向导创建的应用程序源文件(helloBREW.c)。如果你需要了解更多,可以阅读上面提到的第一部分,或者阅读SDK附带的文档。
在这个例程中,你需要知道文件名是非常重要的。特别的,应用程序目录和模块信息文件(.mif)必须目标.dll文件名字相同(也就是前缀相同)。注意,你可以通过打开项目设置对话框(选择项目菜单>设置)的Link选项卡来定义.dll文件的名字。如果你按照第一部分的去做了,应该在相应目录已经有了正确命名的文件。
最后,提醒一下,在本文中“小程序”和“应用程序”这两个词会交替使用,都代表同一事物。
设置Visual C++
在第一部分,所有的必须项目设置都是由BREW应用程序向导来管理。但我们仍然需要提供一个可执行文件以便在调试阶段运行.dll文件,同时还要确保BREW能够找到应用程序的.dll文件。为了满足第一个要求,我们需要为BREW_Emulator.exe提供路径。
为了满足第二个要求,我们要确保链接程序将helloBREW.dll写在项目的根目录里(...\helloBREW\),而不是默认的debug目录(...\helloBREW\debug\)。因为模拟器自动在名为helloBREW的目录里寻找helloBREW.dll。
理解源代码
首先我们来大致了解一下应用程序向导在helloBREW项目中生成的源代码。如果你还没有这么作过,请用Visual C++打开helloBREW项目,然后选择FileView并展开Source Files文件夹。你可以看到3个源代码文件:AEEAppGen.c,AEEModGen.c,以及 helloBREW.c。前两个文件使得我们的应用程序能够绑定到BREW的应用程序执行环境(AEE)。AEEModGen.c管理模块,每个模块(module)基本上包括1个以上互相依赖的小程序(applets)。当一个终端用户激活了一个应用程序,AEE创建模块,由这个模块调用每个应用程序必须提供的AEEClsCreateInstance()函数,依次实例化应用程序。
这让我们开始了解小程序(applet)和应用程序(application)可以(比较宽松)地互换使用的原因。为什么呢?因为小程序可以理解为一个容器,他容纳了仅允许开发人员创建的功能与AEE交互并且在设备上运行的所有文件。举例来说,这样一个容器可以提供对shell服务的接口和对设备显示器的接口。这样我们可以认为一个应用程序是一个小程序加上开发任何创建的功能。实际上,如果在这个例子里我们用C++原理来说明,helloBREW(开发人员创建的功能)要public地从BREW的AEEApplet结构继承,从这个角度看,一个应用程序就是一个小程序(is a的关系)。AEEAppGen.c提供AEEApplet_New()函数,helloBREW将调用这个函数来设置helloBREW应用程序的AEEApplet部分。很快我们会更详细地讨论AEEClsCreateInstance()和AEEApplet_New()。
现在我们对这些部分如何相互结合有了个基本的概念,现在让我们看看BREW应用程序向导生成的框架代码。至于所include的头文件,你可能都已经猜到了,AEEModGen.包含了AEEModGen.c的声明,AEEAppGen.h同样声明了AEEAppGen.c。AEEShell.h提供了shell接口API的声明。如果你希望更多的了解这个重要的接口,可以在BREW SDK附带的BREW API参考里查找IShell。这里我们将不作深入研究,将我们自己的代码加到helloBREW.c中。
现在,我们跳过helloBREW_HandleEvent()的定义来看AEEClassCreateInstance() (也可能是AEEClsCreateInstance(),译者注)。这个函数是helloBREW接触到AEE的地方。当AEE向应用程序传递一个启动的请求,AEEModGen.c中定义的AEEModCreateInstance()就调用小程序(applet)型的AEEClassCreateInstance()函数。因为BREW是单线程的,所以,不论一个模块里有多少个小程序,同一时间只有一个小程序被激活。通过调用ISHELL_StartApplet(),一个小程序可以被另一个小程序启动。在这种情况下,当前的小程序被暂停,转而用ISHELL_StartApplet()提供的class ID调用AEEClassCreateInstance()。显而易见,AEEClassCreateInstance()需要模块里每一个class ID的逻辑分支。在我们的模块里只有一个小程序,因此AEEClassCreateInstance()只需要处理一个class ID。
在前面的文章里,我们记得在helloBREW.mif文件里生成了一个helloBREW的class ID。MIF编

