C言語からJavaへの移植方法まとめ
XPCEというC言語で組まれたPCエンジンエミュレータを、iアプリのJavaへ移植しています。
やっているうちに、移植手順のちょっとしたコツに気がつきました。
そんなわけで、C言語のソースから、Javaへ移植する場合の作業について、まとめておきます。
常に動作テストできるようにする
Cのソースを、いきなりJavaに拡張子変更して、中身を書き換えていくという方法をとると、
すべてをJavaコードに修正するまで、動作確認することができなくなってしまいます。
Javaに拡張子変更するのは、できるだけ後にします。
Cのソースのまま、ビルドして動かせる状態を保ったままで、Javaに無い機能を置換していきます。
ポインタ演算の置き換え
ポインタは配列+インデックスに置き換えます。
「->」を「.」に置き換え
間接メンバ参照演算子「->」を、直接メンバ参照演算子「.」に置き換えます。
Javaには「->」が存在しないためです。
これは簡単に置き換える方法があり、構造体を参照渡しにすればOKです。
void func(HOGE *hoge) { hoge->aaa = 10; hoge->bbb = 10; }
だったら、
void func(HOGE& hoge) { hoge.aaa = 10; hoge.bbb = 10; }
このように書き換えます。
共用体(union)の置き換え
共用体をクラスに置き換えて、メンバへの参照を、ゲッター、セッターを介して行うようにすることで
共用体を使用しないようにできます。
unsigned型の置き換え
Javaで符号なしの型は、char(16bit符号無)だけです。
unsigned char等は、intに置き換えます。
unsigned charの場合、255に1を加えると0に戻りますが、これはAND演算のマスクで代用します。
演算に& 0xFFをつければOKです。
マクロ
マクロはメソッドに置き換えます。
しかし多いとそれなりに面倒です。
マクロがあまりにも多用されているソースの場合、Cコンパイラのプリプロセッサを一度通して
マクロを展開してしまう手もあります。
Visual C++の場合、
cl.exe /EP in.c > out.c
で、マクロを展開したソースを得ることができます。
if文は比較演算子を必ず付ける
Cの場合、ifの条件式が数値型でもOKなので、以下のような書き方をよくします。
int var = getVer(); if (var) { varが非ゼロの場合の処理 }
これを比較演算子を使うように書き換えます。
int var = getVer(); if (var != 0) { varが非ゼロの場合の処理 }
Javaでは、ifの条件式はboolean型しか使えないためです。
とにかく、ちょっとづつやっていくのがポイント
ある程度の規模と複雑さがあるソースの場合、移植時にバグを入れてしまうと後で見つけるのは困難です。
すこし直してはビルド&動作確認し、ちょっとづつやっていくのが良いです。