TOP MAP UP

C++ Classのprivateメンバ関数のテーブル

 以前にも「クラスのメンバ関数のポインタを渡したい」というような話を書いたのだが、今回エミュレータのデコードにおいて本格的にテーブルジャンプをやってみようと思い、調べてみたので記録をまとめる。

 今回テーブルに並べる関数の定義は
void	op_add(void);
void	op_addc(void);
void	op_addi(void);
 :
void	op_subfic(void);
void	op_twi(void);
void	op_xor(void);
である(まぁ引数があってもそんなに難しくはない)

 結果から言うと、実はテーブルの宣言が一番ポイントだったりする。テーブルの宣言は次のような感じになる
void (PPC403GA::*opt_fc000000[0x040])(void);
void (PPC403GA::*opt_48000003[0x004])(void);
void (PPC403GA::*opt_4c0007ff[0x800])(void);
void (PPC403GA::*opt_7c0007ff[0x800])(void);
ちなみにこれはPPC403GAという同じクラスである。

 テーブルへの代入は次のような感じになる
opt_fc000000[0x03]=&PPC403GA::op_twi;
opt_fc000000[0x07]=&PPC403GA::op_mulli;
opt_fc000000[0x08]=&PPC403GA::op_subfic;
opt_fc000000[0x0a]=&PPC403GA::op_cmpli;
opt_fc000000[0x0b]=&PPC403GA::op_cmpi;
opt_fc000000[0x0c]=&PPC403GA::op_addic;
この例では直接代入しているが(そちらの方が都合が良かったので)テーブル定義時に列挙するのもありであろう

 実際に関数を呼び出す場合は次のようになる
(this->*opt_48000003[_code&0x003])();
これも同じクラスから呼び出されている(であるのでthis)

とまぁ以上のように書けば(同じクラスの)メンバ関数を、配列に入れた関数ポインタで呼び出すことが出来る。
やってみると大したことはないのだが、結構わからなかったので、同じ問題を抱えている人の為にメモしておく