Mobile:NEWS 2003年11月7日 00:33 AM 更新

BREW プログラミング入門(3)
画面に描画をしてみよう(2/3)


前のページ

BREWに用意されているインタフェース

 BREWに用意されているインタフェースにはどのようなものがあるか、調べてみましょう。BREW SDKの「BREW APIリファレンス」を開いてみましょう。HTMLヘルプ (あるいは PDF) の左側の目次に、たくさんのインタフェースが並んでいるのが分かるでしょう。

 試しに、IFileMgrインタフェースを調べてみてください。これは、携帯電話上のファイルシステムにアクセスするためのインタフェースです。例えばIFILEMGR_OpenFile()関数を使うと、ファイルを作成したり、読み書きすることができます。

オブジェクトの作成と取得

 それでは、IFileMgrオブジェクトはどのようにして作成したらよいでしょうか。IShellオブジェクトやIDisplayオブジェクトは、アプレット構造体であるAEEAppletが保持しており、すでに作成されているものでした。

 それ以外のインタフェースのオブジェクトは、IShellのISHELL_CreateInstance()関数により作成することができます。

int ISHELL_CreateInstance ( IShell* pIShell, // IShell オブジェクト AEECLSID cls, // 作成するオブジェクトのクラスID void** ppobj // オブジェクトが返される )

 第2引数にはクラスIDを指定します。BREWアプレットのクラスIDと同様に、すべてのBREWインタフェースにはクラスIDが割り当てられています。

 インタフェースのクラスIDの一覧は、「BREW APIリファレンス」の末尾のほうにある「AEECLSIDリスト」で見ることができます。あるいは、BREW SDKをインストールしたフォルダ内のinc\AEEClassIDs.hファイルに定義されていますので、これを見ることもできます(ただし、この両方にも記載されていないクラスIDもあります。例えばAEECLSID_3DはAEE3D.hで定義されており、ドキュメントには記述されていません)。

 基本的に、AEECLSID_にインタフェース名の大文字を連結したものがクラスIDを表す定数となります。例えば、IBitmap のクラスIDはAEECLSID_BITMAP、IDatabaseのクラスIDはAEECLSID_DATABSEとなります。

 例として、IFileMgrオブジェクトを作成するコードを以下に示します。

IFileMgr* filemgr; ISHELL_CreateInstance(shell, AEECLSID_FILEMGR, &filemgr);

 ISHELL_CreateInstance()以外にもオブジェクトを取得できる関数があります。例えば、IFileMgrインタフェースのIFILEMGR_OpenFile()関数により、IFile オブジェクトを取得することができます。

IFileMgr* filemgr; IFile* file; ISHELL_CreateInstance(shell, AEECLSID_FILEMGR, &filemgr); file = IFILEMGR_OpenFile(filemgr, "sample.txt", _OFM_READ);

 このように、「BREW APIリファレンス」に記載されているインタフェースのオブジェクトは、IShell インタフェースで作成するか、あるいは別のインタフェース関数を呼び出すことで取得できるようになっています。

上記のようなファイルシステムにアクセスするインタフェースを使用する場合、MIFファイルの [全般] タブの [特権レベル] で [ファイル] を選択しなければ動作しません。

オブジェクトの破棄

 オブジェクトの作成の方法は分かりました。ではオブジェクトの破棄はどのようにするのでしょうか。オブジェクトを破棄することができなければ、オブジェクトがどんどん増えつづけてメモリを食い尽くしてしまうはずです。

 BREWでは、オブジェクトの寿命管理に "参照カウント法" を用います。BREWのオブジェクトは、"参照カウント" と呼ばれる整数を保持しており、IXXX_AddRef()関数を呼び出すことで参照カウントが1つ増え、IXXX_Release()関数を呼び出すことで参照カウントが1つ減り、参照カウントが0になった段階で、オブジェクトは破棄されます(ここで IXXX はインタフェースの名前です)。

 インタフェース関数を使用してオブジェクトを取得するとき、オブジェクトの参照カウントが一つ増えた状態で返されるため、そのオブジェクトが不要になったときにIXXX_Release() 関数を呼び出す必要があります。

 具体例を示しましょう。下記のコードは、BREWでファイルを読み取るときの一般的なコードを示しています。まず、ISHELL_CreateInstance()により IFileMgrオブジェクトを作成し、IFileMgrのIFILEMGR_OpenFile()により IFile オブジェクトを作成します。

 それぞれのオブジェクトは、作成したときに参照カウントが1つ増えますので、オブジェクトが不要になったら、それぞれのIXXX_Release()を呼び出すことで、参照カウントを一つ減らしています。減らしたときに参照カウントが0になればオブジェクトは破棄され、メモリ上から削除されます。

void ReadFileSample(AEEApplet* app) { IShell* shell = app->m_pIShell; IFileMgr* filemgr; IFile* file;

// IFileMgr オブジェクトを作成する。 // この段階で IFileMgr オブジェクトの参照カウントが 1 増える。 ISHELL_CreateInstance(shell, AEECLSID_FILEMGR, &filemgr); { // IFile オブジェクトを作成する。 // この段階で IFile オブジェクトの参照カウントが 1 増える。 file = IFILEMGR_OpenFile(filemgr, "sample.txt", _OFM_READ); { // ここで file からデータを読み取る。 } // IFile オブジェクトが不要になったので Release() を呼び出して // 参照カウントを 1 つ減らす。 // ここでもし参照カウントが 0 になったら、 // オブジェクトは実際に破棄される。 IFILE_Release(file); } // 同じく IFileMgr オブジェクトの参照カウントを 1 つ減らす。 IFILEMGR_Release(filemgr); }

 参照カウントとは、「そのオブジェクトを必要としている者の数」です。必要としている者がいなくなれば、オブジェクトは自動的に破棄されます。一般に C/C++ 言語では「そのオブジェクトを誰が破棄するのか」という問題が常につきまといますが、参照カウント法を使えば、この問題を気にかける必要がなくなります。

BREWの参照カウントのメカニズムは、WindowsのCOMインターフェイスとまったく同じです。WindowsのCOMプログラミングを経験された方であれば、容易に理解できることでしょう。

Javaでは「そのオブジェクトを誰が破棄するのか」問題に対処するために、言語自体にガーベージ コレクションという機能が備わっているため、プログラマーは全く気にする必要がありませんでしたが、Javaも内部的にはBREWと同じような管理を行っています。

IGraphicsインタフェース

 IDisplayインタフェースを使った描画の方法については理解できたでしょうか。AEEAppletから IDisplayオブジェクトを取得し、IDisplayインターフェイスの関数により描画処理を行い、最後にIDisplay_Update()を呼び出すことで、実際の画面に反映させる、たったこれだけです。

 しかし、「BREW APIリファレンス」をよく調べてみると、IDisplayでは長方形や直線など、単純な図形しか描画できないことが分かるでしょう。

 BREW 2.0以降では、描画用のインタフェースとして、IDisplayに加えてIGraphicsが提供されています。このインタフェースでは、円、円弧、扇形、楕円、楕円弧、三角形、角丸四角形、多角形など、多彩な図形を描画できるようになっています。またクリッピング、相対座標描画、ビューポートなど複雑な描画処理もサポートしています。

 IGraphics による描画のサンプルを以下に示します。

void GraphicsSample(AEEApplet* app) { IGraphics* graphic; AEECircle circle;

// IGraphics オブジェクトの取得 ISHELL_CreateInstance(app->m_pIShell, AEECLSID_GRAPHICS, &graphic);

// 背景を白でクリア IGRAPHICS_SetBackground(graphic, 255, 255, 255); // 背景色は白 IGRAPHICS_ClearViewport(graphic); // 画面全体を 背景色で塗りつぶす

// 赤い円を描く circle.cx = 50; // 円の中心の X 座標 circle.cy = 50; // 円の中心の Y 座標 circle.r = 20; // 円の半径 IGRAPHICS_SetColor(graphic, 255, 128, 0, 0); // 境界線は橙色 IGRAPHICS_SetFillMode(graphic, TRUE); // 円の中を塗りつぶす IGRAPHICS_SetFillColor(graphic, 255, 0, 0, 0); // 円の中は赤色 IGRAPHICS_DrawCircle(graphic, &circle); // 円を描画する

// 画面ビットマップへの描画を実際に表示する IGRAPHICS_Update(graphic);

// IGraphics オブジェクトの解放 IGRAPHICS_Release(graphic); }

 IGraphicsは、IDisplay のようにAEEApplet構造体がすでに保持しているオブジェクトではないので、IShellを利用してオブジェクトを作成する必要があります。また、オブジェクトを作成したら必ず解放する必要があります。

 その他の描画操作は、上記コードのコメントを見るとすぐにお分かりでしょう。インタフェース関数の詳細については、「BREW APIリファレンス」を参照してください。

[倉谷智尋, ITmedia]

Copyright © ITmedia, Inc. All Rights Reserved.

前のページ | 2/3 | 次のページ



モバイルショップ

最新スペック搭載ゲームパソコン
高性能でゲームが快適なのは
ドスパラゲームパソコンガレリア!

最新CPU搭載パソコンはドスパラで!!
第3世代インテルCoreプロセッサー搭載PC ドスパラはスピード出荷でお届けします!!