PSPであそぼう(5)

試しに、自分の環境で「ld -verbose」とタイプして、ldのディフォルトのリンカスクリプトを出力させてみると良い。


たいていの環境なら、.ctor(コンストラクタのセクション)とか.dtor(デストラクタのセクション)とか書いてあるところに、__CTOR_LIST__とか__DTOR_LIST__いう文字が見えるだろう。こいつが「コンストラクタのリスト」と「デストラクタのリスト」である。こいつの先頭には、リストに登録されている関数ポインタの数が入っている。-1ならば、数は入っていなくてリストの最後に0(null)が登録されている。


こいつさえ見つかれば、あとは


typedef void (FuncVoid)();

extern "C" FuncVoid* __CTOR_LIST__[];
extern "C" FuncVoid* __DTOR_LIST__[];

void invokeFuncList(FuncVoid** list)
{
int count = (int)*list++;
if (count == -1)
{
for (; *list != 0; list++) (**list)();
}
else
{
for (int i = 0; i < count ; i++, list++) (**list)();
}
}


とでもやって、スタートアップルーチンを



extern "C" void pgMain(){
invokeFuncList(__CTOR_LIST__); // staticなobjectのconstructorを呼び出す
Main();
invokeFuncList(__DTOR_LIST__); // staticなobjectのdestructorを呼び出す
}

とでも書けばいっちょあがりである。上の例ではわかりやすいようにC言語で書いたが、アセンブラで書いてスタートアップルーチンに組み込んでももちろん構わない。(つづく)