『HelloWorld』プログラムを基に、BREWアプリケーションの全体像を詳しく解説する。「BREWモジュール」「BREWアプレット」とは一体?
前回「BREWアプリケーション開発の流れを押さえよう」では、開発環境の構築から、「Hello World」の表示までを実践し、本連載の導入部として、環境構築の確認とプログラムの実行方法にフォーカスして解説を行いました。
今回は、前回説明を省いた“プログラムの詳細部分”について詳しく見ていきたいと思います。
まず、前回作成した「HelloWorld」プログラムを利用しながらBREWアプリケーションの全体像を俯瞰(ふかん)してみましょう。
BREWアプリケーションは、定義ファイルである「MIFファイル」なども含めて、大きく以下のように構成されています(図1)。
ここのポイントは、「BREWモジュール」と「BREWアプレット」です。
BREWモジュールとは、BREWアプリケーションを格納するための“コンテナファイル”です。Windows上のシミュレータで実行する場合はDLLファイル、実機上のARMバイナリであればMODファイルとなります。そして、このBREWモジュールがどのようなファイルなのかを定義しているのがMIFファイルです。MIFファイルは、BREWモジュールと1対1の関係にあります。
そして、このBREWモジュールの中に格納されているのが、BREWアプリケーションの実体であるBREWアプレットです。BREWアプレットは、構造上BREWモジュールの中に複数存在させることが可能なため、これらを識別するために「クラスID」というIDが割り振られています(注1)。なお、このクラスIDを格納しているのが、MIFエディタで作成した「BIDファイル」です。
このBIDファイルは、プログラム中でincludeすることになりますが、この中身は以下のようになっています。
#ifndef HELLO_BID #define HELLO_BID #define AEECLSID_HELLO 0x01234567 #endif //HELLO_BID
前回、MIFエディタで設定した値が「AEECLSID_HELLO」としてdefineされていることが分かります。「BREW AEE(Application Execution Environment)」は、この「AEECLSID_HELLO」とプログラム中で定義されたクラスIDから、BREWアプレットであるHelloWorldプログラムを識別しています(図2)。
では、BREWアプリケーションの実体であるBREWアプレットは、BREW AEE上でどのように動作しているのでしょうか。
BREWアプレットは“アプレット”の名前が示すとおり、BREW AEEに組み込まれてはじめて動作するプログラムです(注2)。
そのため、プログラム中には「main関数」に相当するものはなく、実行の主体となるのはBREW AEE側ということになります。BREWアプレットは、アプリケーションの主体であるBREW AEEの命令をトリガーとして動作する“プログラムモジュール”といってもよいでしょう。Javaを知っている方であれば、「Java Applet」や「Java Servlet」と似たような仕組みだと思っていただけると、イメージしやすいかもしれません。
ここで、前回作成したHelloWorldプログラムを思い出してください。「BREW Application Wizard」で生成された3つのファイルのうち、中身を修正しなかったファイルが2つありました。その2つのファイルとは、「AEEModGen.c」と「AEEAppGen.c」です。
関連リンク: | |
---|---|
⇒ | BREWアプリケーション開発の流れを押さえよう |
これらのファイルには、BREW AEEがBREWアプリケーションを実行する際に必要な関数が実装されており、BREWアプリケーションのテンプレートでもあり、かつ、ベースとなるものでもあります。
基本的に、この2つのファイルは変更せずに利用します。プログラマが扱うものは、あくまで初期化やイベント処理などが記述されたアプレットの内部処理の部分(HelloWorldプログラムでは「hello.c」)です。「AEEModGen.c」と「AEEAppGen.c」には、BREWモジュールとBREWアプレットのロード、アンロードなどに関する記述があり、この2ファイルの中にBREWアプリケーションの動作を紐(ひも)解く鍵があります。
まず、「AEEModGen.c」の中を確認してみると、以下の関数にBREWアプリケーションを起動するポイントがあります。
int AEEStaticMod_New(int16 nSize, IShell *pIShell, void *ph, IModule **ppMod,PFNMODCREATEINST pfnMC,PFNFREEMODDATA pfnMF)
AEEModGen.c(抜粋) |
この「AEEStaticMod_New()」は、BREW AEEがBREWモジュールをロードする際に行われる処理が記述されています(実際には、「AEEMod_Load()」が呼ばれているのですが、これは環境依存を抽象化する関数で、実質的には「AEEStaticMod_New()」が重要になります)。この「AEEStaticMod_New()」の内部で行われる重要な処理が「IModuleインターフェイス」の実装です。
IModuleインターフェイスとは、BREW AEEがBREWモジュールを管理するためのインターフェイスを提供するもので、BREW AEEはこのインターフェイスを介して、BREWモジュールのライフサイクルなどを管理します(注3)。
以後、BREW AEEはIModuleインターフェイスに定義されている名前で、BREWモジュールにアクセスするようになります(図3)。BREW AEEは、BREWモジュール側の決められた名前にアクセスすればよく、また開発者はBREW AEEに手を入れずにアプリケーションの開発に集中できます。
例えば、「AEEModGen.c」の中にある関数は、以下のようにインターフェイスとして実装されています。
インターフェイス | 実体の関数 | |
---|---|---|
IMODULE_CreateInstance() | AEEMod_CreateInstance() | |
IMODULE_AddRef() | AEEMod_AddRef() | |
IMODULE_Release() | AEEMod_Release() | |
IMODULE_FreeResources() | AEEMod_FreeResources() | |
「AEEMod_Load()」がインターフェイスではない理由は、エントリポイントであるため、当然、実行環境に依存するからです。これはシミュレータ環境だとWindowsのDLLとなるため、以下のように定義されていることからもその理由がよく分かると思います。
__declspec(dllexport) int AEEMod_Load(IShell *pIShell, void *ph, IModule **ppMod)
Copyright © ITmedia, Inc. All Rights Reserved.