BREW はオブジェクト指向な開発環境?
BREW SDK に付属するサンプルアプリはC言語で記述されていますが、オブジェクト指向プログラミング言語 C++ で BREW アプリを開発できます。 BREW アプリを C++ 言語で開発するためのプログラミング環境として SophiaFramework があります。
SophiaFramework : BREW C++ ライブラリ & GUI フレームワーク & XML ミドルウェア
C 言語のメリット・デメリット
C のメリットは C++ よりも実行速度が速い点にあります。しかし、コンパイラの知識があれば、C と同等の速度で実行する C++ プログラムの開発も可能です。
C のデメリットはカプセル化が難しい点にあります。アプリケーションが大きくなると、複雑さは急激に増します。 カプセル化せずに開発を進めると、保守が困難で、再利用しにくいコードになります。( リスト 1 )
▼リスト1 カプセル化されていないコード IFile* file; // IAStream* 型へのキャストが必要です。 IASTREAM_Read((IAStream*)file, buffer, sizeof(buffer));
C++ では、モジュールは自動的にカプセル化されます。( リスト 2 )
▼リスト2 カプセル化されたコード SFBFile* file; SFBAStream* stream; // アップキャストは自動的に行えます stream = file; // APIがカプセル化されています stream->Read(buffer, sizeof(buffer));
メディアプレイヤー、3D オンラインゲームのように大規模で複雑な携帯電話アプリでは C++ で開発するのが効率的です。
どのようにC++を利用するか
最初に、Qualcomm 社の C 言語ベースの BREW インタフェースをすべて C++ でラップします。
SophiaFramework では、すべての BREW インタフェースに対応したラッパークラスが含まれています。( リスト 3 )
▼リスト3 SophiaFramework を用いたBREW インタフェースの操作 void function(SInt16 index) { SFXAnsiString name; SFBFileMgrSmp filemgr; SFBFileSmp file; ... name = "config/" + SFXAnsiString::Format("%02d", index) + ".txt"; file = filemgr->OpenFile(name); return; }
SophiaFramework では、文字列クラスがあります。文字列の演算がシンプルに記述できます。文字列演算時の煩雑なバッファ処理はすべて内部的に処理されます。
new / delete 演算子
C++ の new 演算子や delete 演算子が BREW SDK では標準で提供されません。コンストラクタやデストラクタを実装するには、new 演算子や delete 演算子を定義する必要があります。( リスト 4 )
そして、リスト 5 のようにグローバル関数を定義して、演算子をオーバーロードします。
▼リスト4 実装の例 void* operator new(size_t size) throw() { return MALLOC(size); } void* operator new(size_t /*size*/, void* address) throw() { return address; } void* operator new [](size_t size) throw() { return MALLOC(size); } void* operator new [](size_t /*size*/, void* address) throw() { return address; } void operator delete(void* address) throw() { FREE(address); return; } void operator delete(void* /*address*/, void* /*dummy*/) throw() { return; } void operator delete [](void* address) throw() { FREE(address); return; } void operator delete [](void* /*address*/, void* /*dummy*/) throw() { return; }
▼リスト5 宣言の例 extern void* operator new(size_t size) throw(); extern void* operator new(size_t size, void* address) throw(); extern void* operator new [](size_t size) throw(); extern void* operator new [](size_t size, void* address) throw(); extern void operator delete(void* address) throw(); extern void operator delete(void* address, void* dummy) throw(); extern void operator delete [](void* address) throw(); extern void operator delete [](void* address, void* dummy) throw();
BREW では、ARM 社の RVCTB コンパイラの制約により、演算子は inline 関数ではなく通常の関数として定義します。
コンパイラ・リンカオプションの変更
BREW SDK の IDE 拡張ツールの中に ARM コンパイラ用 makefile 自動生成ツールがあります。リスト 6 は自動生成されたリンカオプションです。
▼リスト6 リンカオプションの例(変更前) # the -entry flag is not really needed, but it keeps the linker from reporting # warning L6305W (no entry point). The address LFLAGS = $(ROPILINK) -rwpi -entry 0x8000#
実行コードのエントリアドレスを意味する-entry オプションが重要です。 RVCTB リンカは、-entry が "0x8000" の時はコードを最適化しません。 リスト 7 のように "AEEMod_Load" に変更するとコードが最適化されます。
▼リスト7 リンカオプションの例(変更後) # the -entry flag is not really needed, but it keeps the linker from reporting # warning L6305W (no entry point). The address LFLAGS = $(ROPILINK) -rwpi -entry AEEMod_Load
※ -entry が "0x8000" のままであれば、リンク後のアプリサイズは大きくなります。