- - PR -
今回は、イディオム編の第3弾として前回「Symbian流“日本語表示”と“文字列操作”」に引き続き“文字列”について解説します。
前回は、文字列インスタンスを作る練習で紙幅が尽きてしまったので、今回は「作った文字列インスタンスの具体的な使い方」について見ていきましょう。
Walk, don't run.
− ヘッダファイルをのぞいてみる
突然ですが、ヘッダファイルを読んでいますか? Javaや.NET系の言語と異なり、由緒正しいコンパイル言語であるC++ではソースコードはいざ知らず、ヘッダに関してはその内容を隠すことができません(注1)。ドキュメントよりも雄弁にクラスやAPIの仕様を語っているものがあるのですから、読まない手はありません。ドキュメントを読んでも分からない部分と出合ったとき、ヘッダファイルは貴重なヒントをワレワレに提供してくれます。
例えば、Symbian OSに限らずAPIのドキュメンテーションでよく見受けられる文言「××××を行った場合の結果は保証されない」。何をやるべきではないか(Don't)は分かりますが、それがなぜだか(Why)はどこにも書かれていません。なぜダメなのだろうという理由をあれこれ考えるとき(モデリングですね)、ハードの制約や過去の事例、一般論などさまざまな根拠を援用することになりますが、ヘッダファイルほど直接的に役立つものはありません。良い開発者とはできることだけではなく、できないこと(とその理由)を理解している人のことですが、Symbian OSにおいてそうなるためにはヘッダファイルをのぞいてみることが欠かせないように思います(注2)。例えば、前回の最後に出したQUIZ、アレがなぜまずいのかを理解するにはヘッダに書かれている情報がどうしても必要になります。
というわけで、いつかは必ずやらなきゃならないヘッダファイルのアナリーゼを、文字列クラスとの絡みでやってしまおうというのが今回の企みでアリマス。
| 注1:JavaDocは確かによくできた仕掛けですが、しかしヘッダファイルが公開できるようになっていたとしたらアレほどまでに熱心に使われたかというとはなはだ疑問です。逆にぞんざいなドキュメントを付けただけのjarファイルが提供されると、殺意に近いものを覚えることがアリマス。C++はヘッダファイルから定義情報が漏れるから言語としては不完全だという意見を耳にすることがありますが、開発を行う立場からすると利用できる情報が多くて困ることはありません。 |
| 注2:実行単価や設計者の意図を考えず、APIを呼びたいように呼んでおいて、得られた結果が欲しかったものだ、と開き直る態度のことを“What you get is what you want”といいます。かなりの数のソフトウェアエンジニアが大なり小なりこの病にかかっています。 |
文字列クラスのヘッダを見てみよう
Symbian OSにおける文字列クラス群は以下のような構造を持つと、ファーストシーズンの第5回「堅牢で省資源な文字列“ディスクリプタ”」および前回で述べました(図1)。

図1 文字列クラス体系図
確かにそのとおりではあるのですが、前回「Symbian OSでの1文字は16ビットの幅であるUCS-2である場合と、8ビット幅であるCP1252である場合の2通りがあり得ます」(大意)とも書いています。では、図1のクラス構成は2種類の文字コードを許すようなものでしょうか。
こういうときこそヘッダファイルの出番です。第3回「Symbian OSから見放されないための大事な約束」で説明したとおり、S60の「3rd Ed FP2」をインストールするとC:\S60\devices\S60_3rd_FP2_SDKをルートディレクトリとしてファイルが展開されます。この直下に生成されるepoc32というフォルダに、epoc32(つまりSymbian OS)にとって必要なファイルがすべて格納されます。この中にヘッダファイルを収めているincludeフォルダが存在します。ここがヘッダファイルクエストの起点となるフォルダです(図2)。

図2 ヘッダファイルのルートフォルダ
複数ファイルにまたがって文字列検索ができればどんなツールでも構いません(注3)。C:\S60\devices\S60_3rd_FP2_SDK\epoc32\includeを起点として、TDesCとclassの2つの文字列をANDで含む個所を検索してください(以下、このオペレーションを全検索と呼称します)。これはTDesCクラスの定義を行っている場所を探そうとしてのことです。検索すると以下の2つの行が見つかるはずです(リスト1)(注4)。
C:\S60\devices\S60_3rd_FP2_SDK\epoc32\include\e32des16.h 26: class TDesC16 |
| リスト1 TDesCクラスの定義個所検索結果(抜粋) |
注3:筆者の検索ツールは以下の出力形式を取っています。
|
| 注4:C:\S60\devices\S60_3rd_FP2_SDK\epoc32\include\linebreak.h 12: class TDesC16; のような行も見つかりますが、当該個所を開いてみれば単なるクラス名の宣言のみです。本当のクラス宣言であればクラス名の後に実体が付くので、「;」で文が終わるはずがありません。 |
見つかったクラス定義(リスト1)はTDesCそのものではありませんが、文字が16ビットの幅であるUCS-2である場合と、8ビット幅であるCP1252である場合に対応していそうではあります。早速、e32des16.hおよびe32des8.hをエディタで開いてみましょう。それぞれ確かに16ビット文字、8ビット文字に合わせたAPIが定義されています(配列としてアクセスするための[]演算子のオーバーロードも型別に定義されていますね)(リスト2)(リスト3)。
inline const TUint16 &operator[](TInt anIndex) const; |
| リスト2 TDesC16抜粋 |
inline const TUint8 &operator[](TInt anIndex) const; |
| リスト3 TDesC8抜粋 |
では、TDesCはどこにいるのでしょうか?
TDesCはどこにいるのか?
そこでもう一度全検索です。TDesC16およびTDesC8がTDesCの基となりそうなことはヘッダファイルから何となく了解できます。またC++で別名を定義する場合には1)#define、2)typedefのいずれかを用いる必要があります。以上からTDesC16からTDesCが導出されている場所があるはずだと仮定して、
a)TDesC16とdefineのAND条件
b)TDesC16とtypedefのAND条件
でそれぞれ全検索を行ってみます。結論としてはa)に該当する行はなし、b)に該当する行は以下のようになりました(リスト4)。
C:\S60\devices\S60_3rd_FP2_SDK\epoc32\include\e32cmn.h 1127: |
| リスト4 TDesC16とtypedefのAND条件による全検索結果 |
おぉ!! e32cmn.hに見つかったパターンはまさに期待していたもの、TDesC16を使ってTDesCが定義しているコードです。では、どのような条件でTDesC16 == TDesCとなるのか、詳細を調べるために当該行の周辺を眺めてみることにします。すると、下記のような条件コンパイルが行われていることが判明します(リスト5)。
#if defined(_UNICODE) && !defined(__KERNEL_MODE__) |
| リスト5 e32cmn.h内、TDesC定義のチョット上(抜粋) |
_UNICODE環境であり、かつ_KERNEL_MODE_でなければ(注5)、TDesCはTDesC16であるという定義がこの条件コンパイル文で保証されるわけです(当然TDesC8は条件コンパイルの#else側で、TDesC8 == TDesCであるという定義を行っています)。
というわけで、ワレワレのコンパイル環境においては_UNICODEが定義されており(じゃないと日本語が使えません)、e32cmn.hの条件コンパイルが真になるため、TDesC16 == TDesCが成立することが明らかになりました。あ〜長かったですね。でも、アナリーゼとはこのようなものです。以後、『TDesCとその派生クラスのことを調べるときには、e32des16.hのTDesC16とその派生クラスを見ればよいことが保証された』のですから、それはそれで素晴らしいことなのです。
| 注5:KERNEL_MODE_とはカーネルで動くコードをコンパイルするときに定義するシンボルです。ここから先に興味がある方は「Symbian OS Internals リアルタイムカーネルプログラミング」という書籍がありますので、まずはそちらをご覧ください。 |
ホワイトペーパー(TechTargetジャパン)
組み込み開発フォーラム 新着記事
- テストでの「ダメな猫」「普通の猫」「優秀な猫」(2010/3/19)
- 目指せETロボコン!! ライントレースとシステム制御(2010/3/18)
- ミップスとDMPがAndroid on MIPSで協業(2010/3/18)
- 【問題9】 アナログをデジタルに変換する「AD変換」(2010/3/17)
- 組み込みシステム開発における“モデル”とは?(2010/3/11)
- 組み込み向けAndroid「Embedded Master」を公開(2010/3/10)
- Androidでビジネス拡大を狙うミップスの新戦略(2010/3/9)
- MATLAB/Simulinkプロダクト・ファミリ R2010aを発表(2010/3/8)
- 各種カード決済/通信方式に対応した携帯型POS(2010/3/5)
- 【問題8】 「ウォッチドッグタイマ」の役割とは?(2010/3/4)
- アクテル、ミックスド・シグナルFPGA「SmartFusion」(2010/3/3)
- 素晴らしきファイルシステムのデータ管理(2010/3/2)












