連載
» 2009年09月15日 14時45分 UPDATE

BREWアプリケーション開発入門(3):BREWアプリケーションの構成を理解しよう!

BREWの基礎から開発環境の構築・アプリケーション開発までを順を追って紹介。環境構築の確認とプログラムの実行方法を解説した前回に続き、今回は“プログラムの詳細部分”について詳しく見ていきたい。

[末永 貴一/エイチアイ,@IT MONOist]



 前回「BREWアプリケーション開発の流れを押さえよう」では、開発環境の構築から、「Hello World」の表示までを実践し、本連載の導入部として、環境構築の確認とプログラムの実行方法にフォーカスして解説を行いました。

 今回は、前回説明を省いた“プログラムの詳細部分”について詳しく見ていきたいと思います。

BREWアプリケーションの全体像

 まず、前回作成した「HelloWorld」プログラムを利用しながらBREWアプリケーションの全体像を俯瞰(ふかん)してみましょう。

 BREWアプリケーションは、定義ファイルである「MIFファイル」なども含めて、大きく以下のように構成されています(図1)

photo 図1 BREWアプリケーションの全体像

 ここのポイントは、「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ファイル」です。

注1:BREWアプレットは、機能的に複数のアプレットをBREWモジュールに入れることが可能ですが、複数のアプレットを利用するケースはあまりありません。このため、通常のアプリケーション開発では、基本的に“単一のアプレットしか利用しない”と考えて差し支えないでしょう。

 この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)

photo 図2 アプレットの識別について

BREW AEE上での動作

 では、BREWアプリケーションの実体であるBREWアプレットは、BREW AEE上でどのように動作しているのでしょうか。

 BREWアプレットは“アプレット”の名前が示すとおり、BREW AEEに組み込まれてはじめて動作するプログラムです(注2)

注2:アプレットという名称自体に「ほかのアプリケーションの中に組み込まれて実行される小さなプログラム」という意味があります。

 そのため、プログラム中には「main関数」に相当するものはなく、実行の主体となるのはBREW AEE側ということになります。BREWアプレットは、アプリケーションの主体であるBREW AEEの命令をトリガーとして動作する“プログラムモジュール”といってもよいでしょう。Javaを知っている方であれば、「Java Applet」や「Java Servlet」と似たような仕組みだと思っていただけると、イメージしやすいかもしれません。

 ここで、前回作成したHelloWorldプログラムを思い出してください。「BREW Application Wizard」で生成された3つのファイルのうち、中身を修正しなかったファイルが2つありました。その2つのファイルとは、「AEEModGen.c」と「AEEAppGen.c」です。

 これらのファイルには、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)

注3:ここでいうインタフェースとは、オブジェクト指向のインタフェースの概念です。インタフェースの概念により、オブジェクト間のアクセスはお互いの実装を知らなくてもよくなります。BREWは、C言語での実装もサポートしているため、C言語でオブジェクト指向の実装を行っています。

 以後、BREW AEEはIModuleインタフェースに定義されている名前で、BREWモジュールにアクセスするようになります(図3)。BREW AEEは、BREWモジュール側の決められた名前にアクセスすればよく、また開発者はBREW AEEに手を入れずにアプリケーションの開発に集中できます。

photo 図3 IModuleインタフェースについて

 例えば、「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)

>>「BREW AEE上での動作」の続きは次ページ(MONOistサイトに移ります)で解説します


Copyright© 2016 ITmedia, Inc. All Rights Reserved.