PalmOS 5.x Hack開発講座 第4回 「CodeWarriorで組んでみる」

1.題材

 前回までで、「テキスト入力フィールドの下線を点線ではなくて実線にしてしまう」m68kHackとARMHackを無事に組めたところまでお話が辿りつきました

 今回は、ちょっと本筋から離れてCodeWarriorを使って組んでみるにはどうしたらよいかお話しましょう

 ただ、一番新しいCodeWarriorが必要なのです 現時点での最新版はバージョン9.3ですね バージョン9以降であればARMコンパイラが載っていますのでこれからお話しする内容がほぼそのまま適用できると思いますが、バージョン9.3ではPNOでグローバル変数を使えるようにするスタートアップコードが用意されていたりしていろいろと参考になりますので、特に問題がなければバージョン9.3にアップデートしておくことをお勧めします

 CodeWarriorをお持ちでない方は読み飛ばしてしまってください 特に面白いことはありませんので...

 えー、一応僕の環境を...

 [CodeWarrior Development Studio for Palm OS Platform, Version 9.3, Professional Edition]の英語版と[WindowsXP-SP2-RC2]の英語版でございます

 さて、ここでもフォルダの構成を揃えておきますね 前回cドライブのルートに作成した[ARMHack]というフォルダに、[solidLineHackCW]というサブフォルダを作成して、CodeWarriorのプロジェクトを置くことにします [c:\ARMHack\solidLineHackCW]

 そうそう、[YAHM Dev Info.]からSDKをダウンロードして、解凍したファイルの中から[SysTables.txt]と、[\include]と[\lib]の二つのフォルダを[c:\ARMHack]以下にコピーしてありますか? まだであればコピーしておいてくださいね

2.プロジェクトの作成からコンパイルまで

2.1.[PACE Native Object]ステーショナリーの利用

 空のプロジェクトからはじめても良いのですが、あるものは利用しましょう ここでは[PACE Native Object]ステーショナリーを使います 無ければ[Palm OS ARMlet]ステーショナリーでもいいですよ

 このステーショナリーは、ARMコードに関する部分とリソースを集めてリソースデータベースにまとめてくれる部分の両方が入っているので、これからやろうとしていることにうってつけです

 さて、[File]->[New...]と進んで...

 前回cドライブのルートに作成した[ARMHack]というフォルダに、[solidLineHackCW]というプロジェクトを作成することにします

 こんなふうになりました? では、ごそっとすべて消してしまいましょうね... 邪魔ですから

 はい、すっきりしました では、一旦CodeWarriorを終了して...

 次は、プロジェクトで生成されたフォルダを開いてみてください [c:\ARMHack\solidLineHackCW]でしたね

 ここも、[solidLineHackCW.mcp]以外はごそっと削除

 うん、すっきりですね といって、このままでは進まないので、前回作成したARMHackで使用したファイルのうち、三つをコピーしてきましょう [armc03e8.c]と[armc03e9.c]と[solidLineHack.rcp]です

 これで、下準備はOKです

 さて、CodeWarriorを起動して、細かな設定をしていきましょう

 [PACE Native Object]ステーショナリーでは、デフォルトで[Application]と[PNO - FillRandom]ターゲットが生成されていますので、まずは[Application]ターゲットから

 まずは、[Project Type]を[Merged Resource File]に変更します これは、今回68kコードを持っていない為ですが、68kコードを持つ場合は変更の必要はありません

 それから、[File Name]ですね [solidLineHack-CW.prc]としましょう

 次は、[Type]、[Creator]、[DB Name]の設定... おなじみですね

 [Application]ターゲットはこれでおしまい 次は[PNO - FillRandom]ターゲットに進みます

 まず、名前がおかしいので[Target Name]を[PNO - 03e8]としましょう

 次は、[Output File Name]を[armc03e8.bin]に、[Instruction Set]を[ARM]にします [Thumb]でもいいのですが、うまく行かないときの検証を考えて、アセンブリコードが読みやすいベーシックな[ARM]でいきましょう 

 はい、これだけ 簡単ですね このターゲットは、[armc03e8.bin]を生成しますので、もうひとつの[armc03e9.bin]を生成するターゲットを作っておきましょう

 このターゲットも、特に難しい設定はありません こんな感じで...

 さて、さっきコピーしてきた前回作成の三つのファイルをプロジェクトに落としましょう

 [solidLineHack.rcp]は[Application]ターゲットに、[armc03e8.c]は[PNO - 03e8]ターゲットに、[armc03e9.c]は[PNO - 03e9]ターゲットにそれぞれ追加します そうそう、[YAHM Dev Info.]からダウンロードしてきたSDKの中から、[libarmboot.a]と[libarmui.a]を[PNO - 03e8]ターゲットと、[PNO - 03e9]ターゲットに追加しておきますね

 ここまで、きちんとできれば次のような状態になっているはずです どうでしょうか...

 そうだ、[PNO - 03e8]ターゲットと、[PNO - 03e9]ターゲットを[Application]ターゲットにぶら下げておきましょう

2.2.コードの修正

 さて、いきなりMakeと行きたいところですが、さすがにこのままではビルドできないので、少しの修正が必要です

 まず、[solidLineHack.rcp]はとくにいじりようがないですね このままおいておきましょう

 次、一番目の[FldDrawField]の代わりに呼ばれるコードです [armc03e8.c]でしたね

 では、直していきます といいつつ、ほとんど一緒なので違うところだけ...


#include <Standalone.h>

と、


STANDALONE_CODE_RESOURCE_TYPESTR_ID("armc", RESID);

とが無くなっていますね... この二箇所の記述は、PRC-Tools固有の概念に相当する部分であって、CodeWarriorでは邪魔もしくは意味の無い記述に相当するから切られてしまいました 逆に増えている部分はどこでしょうか...


#define CRID 'SolL'
extern void myApiFldDrawField(FieldType *fldP);

 ここは特に説明は要らないでしょう コンパイル時に引数として渡していた[CRID]をコード中に記述していることと、コンパイラのチェックに引っかからないように関数のプロトタイプ宣言を行っているだけですね

 では、もうひとつ... こっちはだいじかな


#define myApiFldDrawField __ARMlet_Startup__

 さて、何の意味があるのでしょうか...

 実は、エントリポイントの設定に相当することをしているのでした

 CodeWarriorのARMコンパイラは、必ず[__ARMlet_Startup__]をエントリポイントとしてコンパイルを行うように設計されているので、[__ARMlet_Startup__]が必ず存在しなくてはいけませんし、変更もできません

 ただ、先の一文を記述することで、[myApiFldDrawField]をエントリポイントである[__ARMlet_Startup__]として扱ってもらえるようになりますから、実質的にエントリポイントを設定していることに相当する訳であります

 まあ、こんなことしなくても、[myApiFldDrawField]を[__ARMlet_Startup__]に書き直せば済む話なのですが...

 もう一つのほうも見てみましょうか こちらは、二番目の[FldSetAttributes]の代わりに呼ばれるコードを書いてゆきます 先ほど記述した[TRA5]リソースのIDにあわせて、今度は[armc 1001]リソースとして作成しますので、[armc03e9.c]としましたね

 変更点はこちらもいっしょです

2.3.ARMコードのコンパイル

 さて、もう一息 [armc03e8.c][armc03e9.c]とをコンパイルしてもらいましょう [PNO - 03e8]ターゲットと、[PNO - 03e9]ターゲットでしたね それぞれをアクティブにしてMakeしてください

 きちんと、[armc03e8.bin]と[armc03e9.bin]とが生成されたでしょうか されていればOKです

2.4.リソースデータベースにまとめよう

 さて、うまく作ってもらえた[armc03e8.bin]と[armc03e9.bin]を[Application]ターゲットに載せましょう

 あとは、本当にもう一息 [Application]ターゲットをMakeすれば全て終了です

3.試してみよう

 今回もシミュレータが使えないので、いきなり実機です

 まず、フルバックアップを取って、[YAHM]と[solidLineHack-CW.prc]をインストールして...と

 [YAHM]を起動して、[solidLineHack-ARM-CW]にチェックを入れて...

 目をつむって、[Memo]を起動...

 さあ、目を開けて見ましょうか

 うまく行っていますよね

 CWはグラフィカルなユーザインターフェースなので説明が長くなってしまいましたが、難しいことはなにもしていません 単にCodeWarriorの環境に合うようにちょこちょこと修正を入れただけでした 余力があれば、Thumbコードを生成するように変更してみたり、生成されるアセンブリコードを覗いてみたりしてみてください 特にアセンブリコードを覗くことは、かなり良い勉強になりますのでおすすめです

 ああ、あまり複雑なことをやろうとした場合には、スタックオーバフローの憂き目にあいますので要注意 この場合、自前でスタック領域を確保する必要が出てきます これはまた別の機会にでもお話しましょう

 今回使用したプロジェクトはここからダウンロードできるようにしてあります (オリジナルとして手を加えて公開する場合は、クリエータIDを必ず変更してくださいますように)

 次回は応用編として、OS5で変更された構造体を扱う場合、APIコールの部分を自前で用意する方法、コード中にARM、Thumbコードを混在させる方法など織り交ぜながらお話をすすめましょう 題材は「メニューの文字化けを直す」でございます 自前でスタックを確保する方法についてもお話できれば良いなと考えています

 第5回「メニューの文字化けを直す」

質問、感想などはPalmHackersSalonのBBSへ

T-Pilot sekino