2006年02月14日

スマートフォンをマス市場へ──SymbianとNokia

Symbian OS v9.0を投入したSymbianは出荷倍増中。2008年には1台当たりの開発コストが78ドルになり、全携帯電話の25%がスマートフォンとなるという。

 スマートフォン分野のキーワードは“マス市場”となった。2月14日、仏カンヌで開催したモバイル最大規模のイベント「3GSM World Congress 2005」にて、英SymbianとフィンランドのNokiaはそれぞれプレス向けに発表会を開催、マス市場へ向けた戦略を語った。

Symbian OS v9.0でOS強化

 Symbianが2月2日に発表した最新の携帯端末向けOS「Symbian OS v9.0」は、セキュリティ、デバイスの管理機能などを強化し、スマートフォンのマス市場への普及を意識している(2月3日の記事参照)。コアとなるプラットフォームの上に、端末メーカーやオペレータが特定セグメント向けに機能を追加できるレイヤーを持つ。セグメントとしては、エンタープライズ、音楽、ゲームなどを想定している。

sym2.jpg
 SymbianのCEO、デビッド・レビン氏はこの日、Symbianの現状を報告した。2004年出荷されたSymbian OS端末は1438万台。年間平均成長率は115%で、4四半期連続で出荷台数倍増を達成したという。まさに倍倍ゲームでユーザーを増やしている状態だが、スマートフォン自体の市場のパイはまだまだ小さい。2004年第4四半期のスマートフォン出荷台数は568万台。同期、世界で出荷された携帯電話の台数は1億9500万台程度といわれている。

 マス市場に向けた取り組みはOSの強化だけではない。米Texas Instrumentsや米Intelとレファレンスデザインを設計し、コスト削減、早期市場投入を手助けしている(10月6日の記事参照)。この日、同社は日立製作所と三菱電機の半導体分野の合弁会社、ルネサス テクノロジとも提携を発表(2月14日の記事参照)。ルネサスの3G端末向けプラットフォームにSymbian OSをポーティングすることで、開発工期を短縮できるとしている。

Series 60 3rd Editionも発表

 そのSymbian OSにおけるUI(User Interface)の1つが、Nokiaの「Series 60」だ。Nokiaはこの日、最新のSymbian OS向けに「Series 60 3rd Edition」を発表。OSと足並みを揃えた。

sym3.jpg
 Symbian OSのUIはほかに、Ericssonの出資を受けるスウェーデンのUIQ Technologyもある。OSとしてMicrosoftやLinuxと競争するだけでなくUI間でも競争がある。Nokiaのモバイルソフトウェア・セールス&マーケティング副社長、アンティ・バサラ氏はこの日、「音楽、ゲームに代表されるマス市場と、これまで通りのハイエンドの2方向アプローチをとる」と戦略を明かした。
※アンティ・バサラ氏の会社名が謝っておりました。お詫びし、訂正させて頂きます

 中でもカスタマイズ化はオペレータ、端末メーカーからの需要が高い部分で、ここへのフォーカスがSeries 60の差別化ポイントとなる。カメラなどイメージング、ビジネス、音楽、ビデオ、ゲームなどのカテゴリに対応する。例えば、イメージングでは高機能マルチメディアレンダリングを実現し、ビジネスではQWERTYキーをサポート。音楽ではOMA DRM 2.0によるダウンロードが実現できるほか、カスタマイズ可能な音楽再生プレイヤーをビルトインで提供する。

 Nokiaは先立って米Macromediaと提携、その一環としてFlashライセンスを取得しており、Series 60端末でFlashが利用できるようになった(2月12日の記事参照)。海外でもFlashはコンテンツプロバイダの注目を集めており、開発者にメリットがありそうだ。

 「Series 60 3rd Edition」は、今年中ごろにライセンス提供を開始する。最初の端末は年内に発表の予定で、ビジネス向けの端末になりそうだという。
2008年、25%はスマートフォンに

 Nokiaでは、2005年2月末でSymbian OS/Series 60ベースのスマートフォンの総出荷台数は2000万台に達すると見込んでおり、2008年、全携帯電話のうち25%がスマートフォンになると予測している。この日、中国のLenovoと英Sendoが、Series 60ベースの端末を発表している。

 Symbian OS全体としては、2004年末時点でライセンス先6社から41機種が提供されており、12社が計40端末を開発中。国内メーカーでは、NTTドコモ向けに富士通、三菱。また海外向けにパナソニックらがSymbian OS搭載端末を提供しており、昨年末にはシャープがこれに加わった(2004年7月8日の記事参照)。

 現在スマートフォンでは最大のシェアを持つのはNokiaだが、日本メーカーの貢献は大きい。レビンCEOは、2003年に「F2051」でSymbian端末を初投入し、以降、テレビ電話機能の「F2102V」、指紋認証機能を搭載した「F900i」や“らくらくホン”、FeliCa搭載の「F900iC」と多岐にわたる端末を投入した富士通を挙げた。

 では、いつスマートフォンはマス市場に浸透するのだろうか? SymbianのレビンCEOは、「素地はすでにある。あとはコストの問題」との見解を示した。「素地」とは、現在世界に出回る携帯電話の80%を供給するメーカーが、すでにSymbian OSのライセンシーとなっているからだ。コストでは、コアの部分でレファレンスデザインや共通セットを利用することで削減につながり、より戦略的な部分となる機能拡張差別化の部分に充当できることになる。

 同社では、2008年には1台当たりの開発コストが78ドルになると試算しており、このあたりが転機になると見ているようだ。
posted by シンビアン at 20:12| Comment(0) | TrackBack(0) | NOKIA SMARTPHONE HACKS | このブログの読者になる | 更新情報をチェックする

Sony Ericsson、Symbian採用のスマートフォンにメモリースティックDuo搭載

Sony Ericsson Mobile Communicationsは、すでにアナウンス済みのGSM携帯電話「P800」に、メモリースティックDuo(以下Duo)スロットを搭載することを発表した。

P800は、3月にすでに発表されていたもので、今回、詳細なスペックが明らかになった。大きな特徴はDuoに対応した点。日本でもDuo対応端末が7月に登場することが明らかにされているが、正式なアナウンスとしては「世界初ということで間違いない」(同社日本法人広報)。容量は16MBのものが同梱され、PCとの各種データ交換や端末のデータをバックアップすることができる。MP3プレイヤー機能も搭載されており、Duo、または端末に保存した MP3ファイルを再生して、付属のステレオイヤホンで楽しむことができる。

デジタルカメラも内蔵されており、撮影画像やPCから転送した画像データをスクリーンセーバーとして利用したり、フォトライブラリーに保存したりできる。内蔵メモリは12MBで、付属の16MBのDuoと合わせ、28MBのユーザーメモリが提供され、十分にデータを保存できる。データの転送は、 Duoだけでなく、Bluetooth、赤外線、ケーブル、と多彩な方式に対応している。

Sony Pictures Digital Entertainmentが提供する、7月公開の「Men In Black II」のゲームが楽しめるのも特徴。映画に登場する武器でエイリアンを倒す射撃ゲームだ。

OSにはSymbian OS v7.0を搭載、UIQと呼ばれるペンで操作するインタフェースを採用していたPDAタイプの端末だ。ストリーミングのメディア再生にも対応、Wordや ExcelといったMicrosoft Officeのデータの編集・閲覧もできる。BluetoothによるPCとのデータ同期も可能だ。

Webは、HTML、XHTML、cHTML、WAPなどの表示に対応し、欧米やアジアにおけるGSM 900/1800/1900のエリアで利用できる。また、中国語バージョンの「P802」も提供される。発売はともに第3四半期の予定。残念ながらGSM 方式のため日本では利用できない。同社日本法人は同様の端末の開発予定はない、とするが、Symbian OS v7.0はCDMA方式にも対応していることもあり、日本での開発も期待したい。
posted by シンビアン at 20:11| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

Sony Ericsson、動画対応のSymbian搭載スマートフォン「P900」を発表

Sony Ericssonは、GSM/GPRSをサポートするスマートフォン「P900」とカメラ内蔵携帯電話「T630」を発表した。それぞれ「P800」と「T610」の後継機種となる。米国、ヨーロッパ、アジア地域向け製品で、2003年第4四半期から2004年第1四半期にかけて発売される予定だ。

P900は、OSにSymbian OS v7.0が採用されている。本体背面にカメラを装備しており、VGA (640 x 480) サイズの静止画、QCIF (176×144) サイズのMPEG4ビデオを撮影できる。

わずか2回のボタン操作で撮影が可能になるなど、操作性の高さが特徴の一つとなっている。機能選択用の5方向ジョグダイヤルのほか、文字入力用にUIQと呼ばれるペン入力ユーザインターフェースを搭載。さらにグラフィカルなインタフェースが、写真やビデオの共有やマルチメディアメッセージの送信をサポートするQuickShare機能を備える。データの転送には、Bluetooth、赤外線、USB接続などが利用できる。

ダイヤルボタン部分を開くとワイドスクリーン・モードに切り替わるデザインに変更はないが、ディスプレイがP800の4,096色から65,536色表示に向上した。内蔵メモリは48MB、さらにメモリースティックDuoスロットを備える。内蔵ブラウザはHTML、WAP、cHTMLなどをサポートする Operaが採用されている。メディアプレイヤーは、静止画/動画以外にMP3の再生をサポートしている。

一方、T630はテクノロジに対する関心は高いが安定した機能を使いたい20代から50代のユーザー層をターゲットにしている。ストレート型のコンパクトな本体に6万5000色表示のカラーディスプレイ、カメラ、Bluetooth機能を搭載し、 QuickShare機能も利用できる。
posted by シンビアン at 20:10| Comment(0) | TrackBack(0) | NOKIA SMARTPHONE HACKS | このブログの読者になる | 更新情報をチェックする

「2010年まで『Symbian OS』がスマートフォン市場をリード」,米ABIの調査

「2010年までは,英SymbianがスマートフォンのOS市場で優勢を維持するだろう」。米ABI ResearchがスマートフォンOS市場の今後の展望について調査した結果を,米国時間4月26日に発表した。

 Symbian社のこれまでの成功は,米MicrosoftによるスマートフォンOS市場の独占を回避しようと,Symbian OSを支持したハンドセット・メーカーやキャリアに負うところが大きい。しかし,フィンランドのNokiaがSymbian社に出資を行っていることから,Nokia社の勢力増大を懸念する向きもある。現に,Nokia社の最大の競争相手である米Motorolaは,同社が保有していたSymbian社の株式を売却して,Microsoft社の「Windows Mobile」を移行しているという。

 スマートフォンOS市場では現在,メーカー独自のOSが98%を占めている。約1000万台に相当する残り2%のシェアを巡って,Symbian社,Microsoft社,Linux開発者がし烈な競争を展開している。

 ABI社は,2009年までに,スマートフォンとWeb対応PDA(携帯情報端末)の出荷台数が,ハンドセット全体の約25%を占めると予測している。また,メーカー独自のOSは機能が限定されているため,より大きなディスプレイや操作性に優れたメニューへの需要が,標準OSに対する需要をけん引するという。
posted by シンビアン at 20:05| Comment(0) | TrackBack(0) | NOKIA SMARTPHONE HACKS | このブログの読者になる | 更新情報をチェックする

2006年02月13日

非同期の処理

例えば、Series60を用いてネットワークを用いたサーバアプリケーションを構築するとしましょう。この際、サーバはクライアントからの接続を待つ必要があります。この「接続を待つ」という行為は明確なタイミングがわかっているものではありません。このような場合、通常は別にスレッドを立て、クライアントからの接続を監視させる事を考えると思います。

また、同一アプリケーションで何らかの時間のかかる処理を走らせている間もユーザーの入力は受け付けなくてはいけないという状況はあるはずです。このような場合も普通に考えるのであれば別にスレッドを立てると思います。今回は、上記のような状況を一般に「非同期の処理」と呼び、その処理をSeries60 上で実現する方法を見てみたいと思います。

マルチスレッドは使用しない?

 Series60では、マルチスレッドを用いたプログラムが可能になっております。しかし、ここで紹介する方法は、マルチスレッドの使用方法を説明するものではありません。スレッドはあくまでもメインのスレッド1本です。非同期の処理を実現するのにスレッドを用いないのは「Series60ではマルチスレッドを用いたプログラムが推奨されない」点に理由があります。マルチスレッドを用いることが推奨されない理由としては

* コンテキストスイッチの切り替えなど、マルチスレッドはリソースを多く消費する
* デットロックの回避等、マルチスレッド特有の問題に対処しなくてはならない

などが挙げられます。

 推奨しないからには、スレッドに変わる非同期の処理を行う機構が必要です。これが「アクティブオブジェクト」と「アクティブスケジューラ」になります。

アクティブオブジェクトとアクティブスケジューラ

 アクティブオブジェクトとアクティブスケジューラは、アプリケーションフレームワークの中で使用されるクラスです。各々の詳細を挙げると、

アクティブスケジューラ
各イベントに応じてアクティブオブジェクトのスケジューリングを行う。アクティブスケジューラ は1つのスレッドにつき1つのみ存在できる。
アクティブオブジェクト
アクティブスケジューラから呼び出され、非同期の処理を行う実体であり、コールバックの関数としてRunL()関数を持つ。

となります。

 つまり「アクティブスケジューラは簡単なスケジューリングを提供する。スケジューリングの対象がアクティブオブジェクトになる」と見ることができます。さらに言えば、「Series60のアプリケーションは、SymbianOSが提供するプロセスごとのスケジューリングと同時に、アプリケーションフレームワーク内部でも各スレッドごとにアクティブスケジューラが行うスケジューリングがある」ということができます。
posted by シンビアン at 21:03| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

コンストラクション(Cクラス)

次に、Cクラスのオブジェクトのコンストラクションに話を移しましょう。オブジェクトのコンストラクションに絡めて、クリーンアップスタックについて見ていきます。

 前回の記事でも多少触れさせていただきましたが、クラスのインスタンスを作成する時は通常、「2フェーズコンストラクション」を行います。2フェーズコンストラクションは、具体的には

* new(ELeave)演算子を用いてクラスのインスタンスが必要とするメモリを確保する。この新たにオーバーロードされている演算子はリーブを発生させる可能性がある。

* 作成したインスタンスが他のオブジェクトを所有する場合(つまりhas-aポインタを持つ場合)は、概ねConstructLという名前の関数でポインタの参照先インスタンスの生成とポインタの値の設定を行う。

 という流れになります。若干厄介に見えますが、これはメモリリーク対策になります。またまた繰り返しになりますが「メモリの確保が最もリソース不足によるエラーを起こしやすい」に注意してください。

 それでは、次の図を見てください。


 携帯環境ですから、非常にリソースが限られています。ですから、小さなオブジェクトの確保でも失敗をする可能性があるわけです。もし、上記のようなコードで、ptr2の初期化に失敗する可能性を考えるのであれば(これは携帯環境では十分に考えられる)、各々のポインタに対して、nullチェックを行う必要があります。これでは、プログラムを書くのが手間になってしまいます。また、リーブの機構があるのですからこれを使わない手はありません。

 そこで、例外処理をすっきりさせるため、先ほど出てきたリーブの仕組みを使うことを考えます。つまり、new(ELeave)を用いてメモリの確保を行います。このオペレータは先述の通り、メモリ確保に失敗するとリーブを発生させます。

 この場合、例外処理はすっきりしますが、新たな問題を引き起こします。それでは、次の図を見てください。


 つまり、リーブが発生した時点でTRAPマクロやTRAPDマクロで処理される箇所までスタックを遡るわけです。2回目のnew(ELeave)でリーブが発生した場合、ptr1が一時的な作業用のauto変数(コンストラクタの中であったとしても十分にあり得る)であれば、そのポインタが永遠に失われ、結果としてメモリリークの原因になります。

 そこで、次のような対策を講じます。

1. CBaseクラスを継承したクラス(ClassA)の使用するメモリのみを確保する(コンストラクタでは何も行わない)。メモリの確保に失敗すれば、リーブを発生させる。

2. ClassAによって所有される他のクラス(has-aポインタでの参照先)は、他のコンストラクション用の関数(一般にConstructL)で初期化する。ここでもリーブが発生する可能性がある。

3. 1または2でリーブが発生した場合、構築途中のオブジェクトへのポインタが失われないようにグローバルな領域(スタック)にポインタの値をコピーしておく(このスタックをクリーンアップスタックと呼ぶ)。

 それでは、2フェーズコンストラクションのサンプルを見てみましょう(Construction.zip)。このサンプルでは、自前でCBaseクラスから派生をしたCMyObjクラスを作成し、このクラスが2フェーズコンストラクションを行います。ただし、意図的にConstructLの関数内でリーブを発生させてる点に注意してください。

 サンプルをビルドしたのち、下記のアイコンのアプリケーションを実行します。


 すると、次のような画面が現れます。


 その後、メニューから「テスト」を選択します。ここでは意図的にリーブを発生させていますので、次のような画面が現れます。


 最後に次のような画面になります。


 ここで、今回のサンプルコードの重要な部分を確認しておきましょう。

CMyObj* CMyObj::NewL(CConstructionContainer* aContainer )
{
CMyObj* ptr = new(ELeave)CMyObj; // インスタンスが使用するメモリの確保
CleanupStack::PushL( ptr );
// (1)以下の処理でリーブが発生したときに備えクリーンアップスタックにpush
ptr->ConstructL(aContainer); // インスタンスのメンバの初期化
CleanupStack::Pop();
// リーブの可能性がなくなったので、クリーンアップスタックからpop
return ptr ;
}

void CMyObj::ConstructL(CConstructionContainer* aContainer)
{
this->iContainer = aContainer ;
TInt reason = KErrNoMemory; // 勝手にメモリがないことにする
User::Leave(reason); // リーブを発生(2)
aContainer->UpdateMessage(_L("初期化完了") ); // この行は実行されない
}

CMyObj::~CMyObj()
{
this->iContainer->UpdateMessage(_L("CMyObj 削除完了"));
}

 ここでは(1)にて構築途中のオブジェクトをクリーンアップスタックにプッシュし、第二フェーズのコンストラクションの(2)において意図的にリーブを発生させています。ここでクリーンアップスタックの重要な動作として、

リーブが発生したとき、クリーンアップスタックに詰まれた
全てのオブジェクトのデストラクタが呼び出される

という点に注意してください。つまり、2フェーズ目で構築に失敗し、リーブが発生しても、クリーンアップスタックにメモリ確保時に取得したポインタを積んでおけば、自動的にデストラクタが呼び出されるということです。そして、リーブ時にデストラクタを呼び出すためにCBaseクラスに仮想デストラクタが定義されているわけです。今回のサンプルコードの画面遷移でも、デストラクタが呼び出されていることが確認できると思います。

 ただし注意点として、リーブ発生時にはクリーンアップスタックに詰まれた全てのオブジェクトがデストラクトされます。つまり、

リーブが発生する可能性が無くなった時点でクリーンアップスタックから取り除く

必要があります。将来、全く別の理由でリーブが発生した場合、問題のないオブジェクトまでデストラクションする可能性があるためです。

次回の予定

 次回は、非同期の処理を見て生きたいと思います。Series60でもスレッドの利用は可能ですが、リソースの消費用の大きさから異なるフレームワークを使用します。この点について確認していく予定です。
posted by シンビアン at 20:58| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

ドメインの再利用

ドメインとは、ある立場から見た場合のシステムの見え方のことでした。ドメインは独立した単位ですので再利用ができます。

ドメインの再利用は何も難しい事ではなく、言ってみれば当たり前の話です。例を挙げると、あるシステムをWebベースで作成した後で、画面や操作はまったく同じにしてJavaで作り直して欲しいと言われた時のことです。こんな時にはデータベースや画面の設計をそのまま持ってきてコーディングだけやり直せばいい、というだけの話です。

しかし、言うだけなら簡単ですが、実際にやってみるとそんなに簡単ではないことがわかるでしょう。ドメインを意識した設計でないと、仕様書のそこかしこにWebの言葉が出てきてしまっているでしょう。「FORMタグを使う」とか「URLに○○のパラメータを含めて……」とか。このようにWebベースであることを前提とした仕様書になっていると再利用することが難しくなります。

こうした場合、本来ならアプリケーション本来の動作を表現するアプリケーションドメインとそれをWeb上で閲覧/操作するためのユーザインターフェースドメインに分けるべきなのです。アプリケーションドメインではURLとかタグとか CGIというような用語は一切使ってはいけません。なぜならそれは本来のアプリケーション(経理とか在庫管理とか)とは一切関係がないからです。そしてしっかりドメイン分けされていれば、関係ない部分が変わっても問題はない、というわけです。
posted by シンビアン at 20:45| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

メタモデル

「メタモデル」とは、モデルをモデル化したものです。「CDには複数の曲が入っていて、曲にはタイトルと作曲者がある」というのがCDというものをモデル化したものだとすると、「オブジェクトには属性があり、それぞれのオブジェクトは関係しあっている」というのがモデルをモデル化したものです。

メタモデルというのは案外いろいろな場所で顔を出します。データベースのテーブル設計がモデル化であるとすると、テーブルの定義方法を設計するのがメタモデルです。プログラムそのものに対して「プログラムには関数と変数があって……」というのがメタモデルです。

メタモデルというのは一種のパターンです。メタモデルはただシステムを開発するだけならさほど意識しなくてもすむのですが、開発スタイルや開発ツールを作成しようとすると目を向けなくてはならなくなります。
posted by シンビアン at 20:43| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

コンベンション

「コンベンション」とは、システム設計に関する規則のことです。「コードコンベンション」という単語が一番馴染みがあるでしょう。コードコンベンションとはコードを書く時の規則のことです。(例えば)Java言語の構文規則のことではありません。それにのっとった上で、例えば関数のコメントはどこに書くかとか、関数名の決め方などを決めたのがコードコンベンションです。当然のことながら、こうした取り決めはいったん決めてしまえばいろんなシステムに適用できます。

コンベンションはコードだけに限りません。仕様書や設計書の書き方、そしてそもそもどんな仕様書を用意するのかなど、システム開発のやり方を規定する様々な規則がコンベンションです。システム開発のモデル化とも言えるでしょう。「システム開発=モデル化」という考え方からすればこれはメタモデルです。

開発するシステムの種類によって適切なコンベンションは変わってきます。小規模システムと大規模システムでは違いますし、データベース系と組み込みリアルタイム系でもまた違うでしょう。その場にあったコンベンションを開発し、それは同じようなシステムで使い回すというのがよいやり方でしょう。
posted by シンビアン at 20:42| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

例外処理(リーブ)

つぎに例外処理を見ていきましょう。また、例外処理に関連して2フェーズコンストラクションについて見ていきたいと思います。このセクションをお読みになるにあたり、しつこいですが「携帯環境のリソースは非常に限られたものを想定している」というのを頭の片隅において置いてください。

 Series60では通常のC++によるtry-catch構文とは異なる例外処理の機構を利用します。これは通常のtry-catchによる例外処理が結果としてコードサイズの肥大化を招くためです。ですから、通常のtry-catchによる例外処理は採用されていません。

 そこで、try-catchの代用として出てくるのが「リーブ(Leave)」という考え方(機構、仕組みといっても良いかもしれません)です。リーブは、従来の例外と概念的にはほぼ同一です。以下にリーブについて概略をまとめます。

* C++の例外の代わりに使用される
* リソースエラー等が発生すると、コードはリーブする
* トラップハーネス(TRAPマクロやTRAPDマクロ)でリーブが処理されるまで関数のスタックをさかのぼる

リーブによる例外処理の例

 それでは、次のサンプルを見てみましょう(LeaveSample.zip)。このサンプルでは、メニューから「リーブのテスト」を選ぶと、意図的にメモリ不足のリーブが発生するようになってます。

// コード例(A)
void CLeaveSampleAppUi::HandleCommandL(TInt aCommand)
{
switch ( aCommand )
{
/// 中略….
case ELeaveSampleCmdAppTest:
{
// 次の関数の呼び出しはリーブを発生させる
this->iAppContainer->TestLeaveL();
break;
}
// 後は省略….

このTestLeaveL()関数の実装は次の通りです。

// コード例(B)
void CLeaveSampleContainer::TestLeaveL()
{
TInt reason = KErrNoMemory; // 勝手にメモリがないことにする
User::Leave(reason); // (1)例外を発生
this->iToDoLabel->SetTextL(_L("問題なく終了しました"));
// 上の一行は実行されない
}

 このサンプルでは、(1)においてメモリ不足のリーブを意図的に発生させています(User::Leave関数でリーブを発生)。このアプリケーションをそのまま実行すると次のような画面がでてきます。

それでは、このアプリケーションに対して例外処理のコードを加えたいと思います。上記コード例(A)を次のように書き換えてみてください。ボールドになっている箇所が書き換えた箇所です。

// コード例(C)
void CLeaveSampleAppUi::HandleCommandL(TInt aCommand)
{
switch ( aCommand )
{
/// 中略….
case ELeaveSampleCmdAppTest:
{
// TRAPDマクロで例外を捕捉
// error に例外コードが入ってくる
TRAPD( error,
this->iAppContainer->TestLeaveL(); );
if( error != KErrNone ){ // 例外が発生しているかを検査
this->iAppContainer->UpdateMessage();
}
break;
}
// 後は省略…

TRAPDマクロの第一引数にあるerrorに例外が発生した理由が格納されます。これをKErrorNone(つまり例外が発生しなかったことを表す)と比較しているわけです。

 もう少しリーブについて見ていきましょう。例外処理自体は、このような形で行うことができます。次に残る問題は「作成した関数、またはAPIで提供されている関数がリーブを発生させるか否か、コンパイラレベルでは判断できない」点にあります。リーブの機構はC++の言語ではなく、Series60で採用されているものです。つまり、例外を適切に処理するのであれば、先のコード例(A)を本来はコード例(C)のようにしなくてはいけません。しかし、コード例(A)のままでも問題なくコンパイルが可能ですし、警告も表示しません。

 そこで出てくるのが関数のコードコンベンションです。今回はコード例(B)で定義した関数は最後に「L」の付く関数になっていますが、一般にリーブを発生させる可能性のある関数はその名前の最後に「L」を付ける習慣になっています。このような「L」の付く関数に関しては(製品としてプログラムを出す場合は)必ずTRAPマクロや今回の様にTRAPDで処理をする必要があります。

補足:今回はリーブによる例外処理を見ていきましたが、一部のAPIには戻り値によって正常/異常終了を表すもあります。
posted by シンビアン at 20:40| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

2006年02月11日

RクラスとMクラス

Rクラス

 Rクラスはシステムリソースを利用するためのクラスになります。SymbianはマイクロカーネルOSですから、システムリソースはサーバアプリケーション(ネットワーク上でのサーバではないことに注意してください)から提供されます。そして、このRクラスがシステムリソースを操作/利用する際のインターフェースになります。従って、通常のクラスとは異なり生成と破棄の方法が異なります。

タイマを使ったサンプル

 ここでサンプルを見てみましょう(RTimerTest.zip)。

ビルド方法:RTimerTest.zipを展開していただくと、次のようなディレクトリ構造になっています。


この中のgroupディレクトリに移動して、
> bldmake bldfiles
> abld build [wins|winscw] udeb

とコマンドを発行してください。winsとwinscwはダウンロードしたSDKにあわせて選択してください。

その後は[スタート]→[全てのプログラム]→[Series60 Developer Tool]から[Emulator (Debug)]を選択してください。

エミュレータを起動した後は


のアイコンを探して、プログラムを起動します。

 このサンプルを起動すると、次のような画面になります。
次に、「オプション」のメニューから「カウント」を選びます。


 すると、次の画面のように右上で5回、カウントを行います。


タイマを使ったサンプルの解説
サンプル1では、Rクラス(つまりOSのサービス)を利用しています。実際に利用している箇所はCRTimerTestContainerクラスのcountというメンバ関数です。
#include
void CRTimerTestContainer::count(){
RTimer timer;
if (KErrNone == timer.CreateLocal())
{
TRequestStatus status;
const TTimeIntervalMicroSeconds32 KTimerInterval = 1000000;
// 一秒間隔でラベルの書き換え
TBuf<8> text;
for( int i = 0 ; i < 5 ; i++ )
{
_LIT(KCount, "Count:%d");
text.Format(KCount, i+1);
CEikonEnv::Static()->InfoMsg(text);
// 文字列のセットと書き込み

timer.After(status, KTimerInterval); // タイマーを開始し
User::WaitForRequest(status); // タイマーの終了を待つ
}
timer.Close(); // timerリソースのクローズ(1)
}
}
ここで重要な点は、RクラスはClose()関数(コメント(1)で書いてある箇所など)で、必ず終了処理を行う必要がある点です。通常のデストラクタ以外に処理が必要です。

Mクラス

 Mクラスは「純粋仮想関数のみを提供するクラス」であり、APIなどに関数等の名前解決を提供するクラスになります。換言すれば、Javaのインターフェースとほぼ同じ役割を持ちます。Mクラスに関しては、後の連載で出てくるサンプルで確認していきたいと思います。
posted by シンビアン at 09:15| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

Mach

読み方 : マーク
別名 : Machマイクロカーネル, マークマイクロカーネル, Mach micro-kernel
分野 : OS

 カーネギーメロン大学のRichard Rashid教授らのグループが米国防総省の援助を受けて開発したマイクロカーネル型のOS。1985年に最初のバージョンが公開され、その後、改良が進められると同時に、商用・非商用を含め多くのOSの基盤部分として採用された。

 Mach自体は、従来のOSの中核部分を抜き出して再構成したようなソフトウェアになっており、その上で動作する多くのサブシステムをあわせて、OSとしての機能を発揮するようになっている。

 また、複数のCPUを動作させるマルチプロセッサ機能や、ネットワーク上に分散したコンピュータが連携するための機能、巨大なメモリ空間のサポートなどが盛り込まれている。

 それまでのUNIX系OSのカーネルは、多くの機能を抱え込んで複雑になりすぎ、また、機種依存コードとそうでないものが混在していたため、他機種への移植に莫大な労力が必要だった。

 これに対し、MachはOSとして必要最低限の機能だけを提供し、また、ハードウェアの設計に依存する部分を自身の内部に隠蔽した。このような設計は、従来の「複雑な」OS基盤(モノリシックカーネル)と区別して「マイクロカーネル」と呼ばれる。

 Machを基盤に採用したOSは、サブシステムを追加することでOSの機能を拡張することができ、また、最小限の労力で他機種へ移植できる。ただし、マイクロカーネルと上位層の通信にかかるオーバーヘッドのせいで、処理速度が向上させにくいという欠点もある。

 当初のMachはまだ多くの機能を自身の中に抱え込んでおり、事実上モノリシックカーネルだったが、バージョンアップするたびに機能を外部に出し、そのたびにパフォーマンスが下がっていった。このため、いったん外に出した機能をカーネル空間に戻したり、ライブラリでエミュレートしたりすることを余儀なくされた。

 こうしたマイクロカーネルの欠点はいまだ克服されておらず、実用性やパフォーマンスを重視する多くのOSはモノリシックカーネルを採用している。

 Machを採用しているOSには、IBM社のOS/2やOSFのOSF/1、Apple社のMac OS X、NeXT社のNEXTSTEPとOPENSTEPなどがある。
posted by シンビアン at 08:35| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

マイクロカーネル 【micro-kernel】

OSの中核部分(カーネル)に最も汎用性の高く機能だけを持たせることでカーネルを小型化する手法。また、そのような手法によって設計されたカーネル。カーネギーメロン大学のグループが開発したMach(マーク)マイクロカーネルがもっとも有名な例。

 マイクロカーネルでは、ファイルシステムや仮想記憶処理などの機能は外部モジュールとして独立しており、カーネル自身は割り込み処理やプロセス間交信などの限られた機能しか持たない。カーネルに出された処理要求の多くは、カーネル内部からプロセス間交信によって外部モジュールを呼び出すことで行われることになる。こうした構造にすることで、カーネル内処理を並列実行することができ、効率を上げることができる。また、機能がモジュールの形で整理されているため、開発効率も上がり、移植や機能追加も容易になる。

 しかし、頻繁に発生するプロセス間通信のオーバーヘッドが大きく、また、CPUの動作モードをカーネルモードとユーザモードで頻繁に切り替える必要があるため、処理速度を向上させにくいという欠点がある。ただし、最新の研究開発の成果によれば、徹底的に機能を絞ってプロセス間通信の効率を向上させることにより、こうしたパフォーマンス上の欠点は克服できるという報告もある。

 マイクロカーネル登場以前の、カーネル自体に様々な機能を実装していく手法を「モノリシックカーネル」という。マイクロカーネルが登場した頃には、モノリシックカーネルは複雑すぎていずれ開発が困難になり、すべてのOSがマイクロカーネルを使うようになるという主張もあったが、LinuxのようなモノリシックカーネルOSの隆盛を見る限り、現在までのところそうした予想は現実とはなっていないようである。

 前述のMachはApple社のMac OS X(とその原型のNEXTSTEP)でコア部分に採用されているほか、当初のWindows NT(NTカーネル)もマイクロカーネル設計であった(現在は様々な機能が追加されてモノリシックカーネルに近くなっている)。
posted by シンビアン at 08:33| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

マイクロカーネル

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動: ナビゲーション, 検索

マイクロカーネルとはオペレーティングシステムの設計思想、及びそのようなOSのカーネル部の名称である。OSが担う各種機能のうち、必要最小限のみをカーネル空間に残し、残りをユーザーレベルに移すことで全体の設計が簡素化でき、結果的に性能も向上できるという考え方。カーネル本体が小規模な機能に限定されるので「マイクロカーネル」と呼ばれるが、必ずしも小さなOSを構成するとは限らない。

マイクロカーネルの出現に伴い、従来型のOSを「モノリシックカーネル」と呼ぶようになった。

特徴

純粋なマイクロカーネルでは、まずカーネル空間で提供される機能を、メモリ空間の仮想化、プロセス制御、プロセス間通信に限定し、割り込みなども全て通信にマップする。その上でファイルシステムやデバイスドライバといった準カーネル機能をそれらのアプリケーションとして実装し、ユーザー空間で動作させる。場合によってはそれらの機能セットをサーバと呼ばれる単位で複数動作させる。

このような形態を持つ事のメリットは、

* OS開発効率の向上(機能拡張、デバッグなどを容易に行える)
* システム全体を止めずにカーネル以外のOSのアップデートを行うことができる
* 必要な機能のみを提供するアプリケーションに特化したOSを構築することが容易になる

などである。また一般にマイクロカーネルでは資源の抽象度が高く、マルチプロセッサ対応やネットワーク透過の通信が自然に実装できるため、大規模な資源利用には有利である。


反面あらゆる場所でプロセス間通信を利用する為、機能相互のオーバーヘッドが大きく、モノリシックカーネルと同等の機能を実装した場合、数パーセントから数倍のロスが出る場合がある。特にコンテキストスイッチのコストを避けるため、必要な機能をカーネル空間に移し、見た目上モノリシックカーネルのように動作させる場合もある(co-location)。

歴史

マイクロカーネルは「UNIXの再設計」という観点から始まっている。

UNIXはファイルという概念でリソースを統一し、ファイルを扱う小さなプロセスをパイプでつないで相互通信させることにより、コンパクトかつ高機能なOS設計に成功した。しかしその後の利用環境の変化に伴い、必ずしもファイルとして扱えないリソースが増加している。例えばネットワーク通信はソケットという概念で行われるが、ソケットはファイルではない。結果的に、後付けで似て非なるコードがOSを肥大化させるという事態が発生したといえる。

OSがたくさんのコードから成る事の直接的な問題点は、

* カーネル自体が占めるメモリ領域(カーネル空間のフットプリント)が大きくなる
* 移植性やメンテナンスに不利

といったものである。さらに、計算機資源の増大に伴いマルチプロセッサや仮想メモリといった、UNIX開発時に想定していなかった概念が出現しており、それらを含めたOS概念のリファインが必要と考えられた。


そこで、「大規模な資源」と「高速な通信」を念頭において「相互通信するプロセスによる協調動作」というUNIXの発展理念に至ったのがマイクロカーネルである。UNIXではファイルを中心概念としていたが、マイクロカーネルではプロセスと通信に主眼を移し、割り込みやI/Oといったあらゆる資源が徹底的に抽象化されている。

なお、この時古くなった計算機資源の再利用も考慮されていた。つまり、移植性が高くコンパクトなOSを使えば、旧式のシステムであってもネットワーク上に接続して資源として活用する事ができるという考え方である。


実際に実装されたMachでは、当初の予想通りコード量の削減には成功した。抽象度が高く、見通しの良いマイクロカーネルはトレンドとしては妥当であり、この時は将来有望な物と見なされている。

しかし問題はマイクロカーネルのパフォーマンス問題が予想以上に大きかった事である。初期のMachは純粋なマイクロカーネルではなく、BSDサーバとの複合カーネルだったがそれでも25%ほどのロスがあり、さらにこれを完全なマイクロカーネルに移行した場合、機能によっては数倍遅くなるという結果が出ている。さらに言えば、マルチプロセッサが浸透するという技術予測が外れた事も大きい。

一方メンテナンス性の面では、典型的なモノリシックカーネル実装であるLinuxの成功により、カーネルの複雑さは心配されたほど大きな問題ではない事が明らかになった。


こうして、一時は「全てのOSはマイクロカーネルに移行する」と考えられていたが、90年代中ごろにはそのような見方は下火になっている。

ただし、以上の問題はマイクロカーネルに利点がないという事は意味しない。実際にNeXTSTEP/Mac OS XやBeOSはマルチプロセッサ対応やCPU移行時の高い移植性など、マイクロカーネルOSであることの利点を活かしている。またLinuxのモジュール機構などは実質マイクロカーネル的な概念であり、利点は利点としてとりいれる傾向があるといえる。

一方マイクロカーネルも性能面での解析が進み、現在第二世代といわれる新しい実装が出現してきている

代表的な実装例とその特徴

* OS-9
o 6809のために設計された、最初の商用マイクロカーネルOS、当時はマイクロカーネルという用語は無く、有用性も理解されておらず、マイコン用途にしてはオーバースペックであった。
* Mach
o カーネギーメロン大学によってもっとも初期に開発され、マイクロカーネルの代名詞ともなったもの。Mac OS XやNEXTSTEP、MkLinuxで使用されている
* L4
o 第二世代マイクロカーネル。高速なメッセージ通信の実装によって、マイクロカーネルの欠点と言われた「メッセージ通信の多さによる非効率性」に対処することを目的にあげており、各種の実装上の工夫によってモノリシックカーネルに遜色ないパフォーマンスを出している。
* Hurd
o GNU によって UNIX 代替をめざし開発されたカーネル。トレンドにあわせ設計がたびたび変更されたため、アナウンス以来長らく登場が待望されていたが、近年動作可能なものが発表された
* Windows NT
o Machをベースにマイクロソフト独自実装のマイクロカーネルを利用。しかし、WindowsNT 4.0以降、パフォーマンス重視の為、各種ドライバをカーネルモードで動作させるようになり、すでにマイクロカーネルの範疇を逸脱しているという考え方もある。(カーネル参照)
* BeOS
o 独自のマイクロカーネル実装。優れたマルチプロセッササポートや、PowerPCからx86への移植の早さはマイクロカーネルの当初の理想を体現した物といえる。現在各種のフリー実装が進んでいるが、ここでもマイクロカーネルの利点が発揮されている。
posted by シンビアン at 08:31| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

Cクラス

 Cクラスは、Tクラス以外の一般のクラスになります。Cクラスは、後に述べる「クリーンアップスタック」の関係から、必ずCBaseクラスを継承しなくてはいけないという制約があります。繰り返しになりますが、携帯などの組み込み環境では「メモリの確保が、もっともリソース不足によるエラーを起こしやすい」点に注意してください。

 CBase クラスは大きく次の二つの機能を提供します。

* ゼロ初期化
* 仮想デストラクタ

 上記の二点は、どちらも後述する「クリーンアップスタック」に関係してきます。長くなりますので、詳細は「コンストラクション(Cクラス)」で見ていきます。
posted by シンビアン at 08:23| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

Tクラス

Series60でのデフォルトのスタックサイズは8KBです。大きなオブジェクトをスタック上に積むのは危険な行為になります。従って、これから利用するクラスのサイズを大まかでも知っておく必要があります。そこで、出てくるのがTクラスになります。Tクラスはスタックに積んでも安全な比較的小さなサイズで、大きさは概ね256bytes以下を目安にします。

 クラス自体の大きさ以外にも、他のオブジェクトを所有しない(つまりhas-aポインタを持たない)クラスである制約があります。これは、携帯などの組み込み環境は「メモリの確保が最もリソース不足によるエラーを起こしやすい」ためです。また、他のオブジェクトを所有しないので、デストラクタが不要になります。

 int型などの組み込みのデータ型は、Tが頭につくようにtypedefされています。以下に、簡単に組み込みのデータ型について触れていきますが、文字列の扱いが特殊であることに注意してください。

基本データ型

 基本データ型はデータサイズが小さいので先頭に「T」が付く型名が使われています。下記のようにtypedefされています。こちらはこれ以上の解説は不要かと思います。

typedef signed int TInt;
typedef unsigned int TUint;
typedef signed char TInt8;
typedef unsigned char TU in t8 ;
typedef short int TInt16;
typedef unsigned short int TUin t16;
typedef long int TInt32;
typedef unsigned lon g int TUin t32;

文字列

 文字列は、char型のポインタを使用しません。基本的に、文字コードがUnicodeになるためです。そこで、char型のポインタを使用するその代わりに「_L」マクロや「_LIT」マクロなどを使用します。ここでは例として「_LIT」マクロの使用方法を次に示します。

_LIT(KHelloWorld, "Hello World!");

 この場合、KhelloWorldが文字列を表す変数(TlitCの型)になり、宣言と初期化が行われます。変数が必要ない場合、例えば引数にそのまま渡したい場合は_Lマクロを使用します。以降のサンプルで_Lマクロを使用したものが出てきますので、そちらのコードも合わせて確認してみてください。

補足:LITマクロに比べて_Lマクロの方は若干効率が悪くなっております。基本的には_LITマクロを使用するほうが良いかと思います。

浮動小数点

 浮動小数点を表す型にはTFloatやTRealなどの型があります。

typedef float TReal32;
typedef double TReal;

 ただしこれらの型に関しては注意が必要です。組み込み環境のアーキテクチャでは、基本的には浮動小数点のサポートを行いません。浮動小数点を含む計算はハードウェアではなく、ソフトウェアで実行する形になります。つまり、浮動小数点の計算が整数の計算などとは異なり非常に時間がかかることになります。

 実際、弊社で作成している組み込み環境向けの3DグラフィックスエンジンであるMascotCapsule(*1)では、小数を表す必要がある場合、高速に動作させる必要性から浮動小数点ではなく(勝手にある桁に小数点があるものと仮定した)、固定小数点を採用しています。

 このようなことから、浮動小数点を含む計算は極力回避するというのが原則になると思います。

posted by シンビアン at 08:23| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

仮想関数について

純粋仮想関数

基本クラスでは,単に主要なメンバ関数と変数を宣言し,必要なものは派生クラスで用意することが多い.すなわち,基本クラスのオブジェクトに対する操作は行わず,これを継承した派生クラスのオブジェクトに対して操作を行うことが多い.

この場合には,基本クラスには仮想関数を使用するための名前だけで実態のないメンバ関数を用意しておけばよいことになる.このとき,純粋仮想関数を使用する.

純粋仮想関数とは,関数定義を持たず,次のような形式をしている.

virtual 型名 関数名(引数リスト) = 0;

この定義では,関数本体が 0 に等しいと定義している.すなわち,関数本体が存在しないことを表す.

このような関数を持つクラスを継承する派生クラスでは,実体のない関数を呼ぶことができないため,必ずその関数を再定義しなおさなければならない.

少なくとも 1 つの純粋仮想関数を含んでいるクラスを 抽象クラス と呼ぶ.抽象クラスは,本体のない関数を含んでいるため,そのクラスのオブジェクトを作成できない.抽象クラスへのポインタは作成でき,実行時のポリモーフィズムは実現できる.

class date {
int y, /* year */
m, /* month */
d; /* day */
public:
virtual bool leapyear() = 0; /* 純粋仮想関数 */
int getyear() { return y; }
};

class seireki: public date {
public:
bool leapyear() { /* 閏年 */
return (getyear() % 400 == 0)
|| (getyear() % 4 == 0) && (getyear() % 100 != 0);
} /* 純粋仮想関数を持つクラスを継承しているクラスでは,
必ず再定義する */
};

class heisei: public date {
public:
bool leapyear() { /* 閏年 */
return ((getyear() + 1988) % 400 == 0)
|| ((getyear() + 1988) % 4 == 0)
&& ((getyear()+ 1988) % 100 != 0);
} /* 純粋仮想関数を持つクラスを継承しているクラスでは,
必ず再定義する */
};

上の例では, leapyear は基本クラス date の中で純粋仮想関数として定義されている.よってクラス date は抽象クラスとなりそのオブジェクトは作成できない.

西暦のクラスと平成のクラスを date の派生クラスとして定義しており,それぞれで閏年かどうかを判定する関数 leapyear を再定義している.

よって,

int main()
{
date *p;
heisei nen;
seireki year;

...
date = &nen;
if (date->leapyear()) {
...
}
date = &year;
if (date->leapyear()) {
...
}
}

のように記述できる.
posted by シンビアン at 08:14| Comment(0) | TrackBack(0) | Symbian OS C++ 実践開発技法 | このブログの読者になる | 更新情報をチェックする

もっとも重要な部分を一気に

前回までは、大まかなGUIアプリケーションの構造を見てきました。今回はSeries60に特有のコードコンベンションや、ANCI C++にはない例外処理の方法、文字列の扱い、さらには2フェーズコンストラクションについて見ていきます。盛りだくさんで少々長くなっておりますがお付き合い下さい。

今回は「論より証拠」ということで、いくつかサンプルコードを用意しております。適宜サンプルコードをダウンロードして、解説と照らし合わせて読んでいただけると幸いです。
携帯上のアプリケーションという特殊な環境

 コードコンベンションの話をする前に、まずは携帯電話というアプリケーションの実行環境の特殊性について見てみましょう。

 昨今の携帯電話は、大きなヒープサイズなどのリソースを持った端末が出てきています。それでも通常のPC環境に比較して、かなり貧弱なリソースしかもっていないのが実情です。例えば、スタックサイズを見ると、Series60はデフォルトでは8KBという、今の感覚からみれば非常に小さいスタックサイズしか持っていません。

注:ただし、このスタックサイズはプロジェクトの設定ファイルで変更が可能です。

 さらに、通常のPCとは異なり、携帯電話は一度電源を投入すれば少なくとも数カ月、長ければ年単位で再起動されることなく動作することが求められます。

 一見、コードコンベンションとは無関係な話のように思えますが、実はSeries60のコードコンベンションはこのような貧弱で、利用条件の厳しい環境を意識したものになっているのです。

クラス(型)名に対するコードコンベンション

Series60ではクラス名や型名に対して4つのアルファベット(T,C,R,M)が先頭につきます。大まかな各々のアルファベットの意味は次の通りです。

Tクラス
サイズの小さいクラスで、スタック上にメモリを確保しても問題のない大きさ
Cクラス
Tクラスよりもサイズの大きなクラス、スタック上に積むのではなく、ヒープ上に確保しなくてはいけない大きさのクラス。このクラスは必ずCBaseクラスを継承する
Rクラス
OSのサービス(システムリソース)を利用するためのクラス。初期化と破棄の方法が通常のクラスとは異なる
Mクラス
純粋仮想関数を提供するインターフェース

 続いて、この各々について見て行きたいと思います。
posted by シンビアン at 08:10| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

Series60 GUIアプリケーションの構造

Documentクラス

 Documentクラスは、アプリケーションの扱うデータ(ファイル等)の管理を行うためのクラスです。したがって、このクラスに記述される処理の多くはファイル関連ということになるかと思います。ここでは、ファイル関連の処理は後の連載に回し、ContainerクラスとAppUiクラスから Documentクラスのポインタを取得する方法を紹介しましょう。

CSample1Document* doc = static_cast(
iEikonEnv->EikAppUi()->Document());

または、もっと単純に

CSample1Document* doc = static_cast(Document());

となります。

最後に、ちょっとしたデバックのヒント

 今回抜き出したHandleCommandL関数の中で

iEikonEnv->InfoMsg(_L("test"));

という記述があります。この記述により、図4のスクリーンショットのような簡単なメッセージをエミュレータ画面右上に出すことが出来ます。

■ 図4

 iEikonEnvメンバはAppUiクラスの中で定義されているのですが、次のように書いても同一のデバックメッセージの出力ができます。

CEikonEnv::Static()->InfoMsg(_L("Test"));

 なお、CEikonEnvクラスはeikenv.hにて定義されていますので、必要に応じてインクルードしてください。

 次回は一般的なコードコンベンション、基本データ型および例外処理の考え方を概観していく予定です。
posted by シンビアン at 08:09| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

Series60 GUIアプリケーションの構造

AppUiクラス

 先述の通り、AppUiクラスはコントローラの役割を果たします。コントローラではユーザーのイベントを受け取り、それを処理するわけです。この「イベント通知用の関数」は「メニューのイベント用(HandleCommandL)」と「キー入力のイベント用(HandleKeyEventL)」の2つがあります。

TkeyResponse CSample1AppUi::HandleKeyEventL(
const TKeyEvent& /*aKeyEvent*/,TEventCode /*aType*/)
{
return EKeyWasNotConsumed;
}

void CSample1AppUi::HandleCommandL(TInt aCommand)
{
switch ( aCommand )
{
case EAknSoftkeyBack:
case EEikCmdExit:
{
Exit();
break;
}
case ESample1CmdAppTest:
{
iEikonEnv->InfoMsg(_L("test"));
break;
}
// TODO: Add Your command handling code here
default:
break;
}
}

HandleKeyEventLには、キーイベントの種類(aKeyType - 押し下げ、押し上げ)と操作されたボタン(aKeyEvent)が、HandleCommandLには選択されたメニューリソースで定義されたリソース IDが引数に渡されます。リソースについても以降の連載で触れる予定です。

Containerクラスでのイベントの処理

 Containerクラスにおいても、キーイベントの処理が可能です。イベント処理を可能にするためには、OfferKeyEventLをオーバーライドする必要があります。

TKeyResponse CSample1Container::OfferKeyEventL(
const TKeyEvent& aKeyEvent,TEventCode aType){
if( aType == EEventKeyDown)
iEikonEnv->InfoMsg(_L("Test"));
return EKeyWasNotConsumed;
}
posted by シンビアン at 08:03| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は1年以上新しい記事の投稿がないブログに表示されております。