__stdcallに関する注意

 __stdcallな関数を関数ポインタで使いたいときとか。



 リンカの「呼び出し規約」の所を見るとわかる、関数の呼び出し方のお話。

てっきり初期値は__stdcallかと思ったら__cdeclだったでござるの巻。



 …まぁ、普通に使っている分には問題ないんだけど、関数ポインタとなると、この部分も合わせて型として扱うようなので。

もし、呼び出し規約が違うようなエラーが見られたら、

// 配列なのは何となくです…。
int *(__stdcall *p_func[2])( int ) =
{
    TestFunc1, TestFunc2
};

こんな感じで呼び出し規約も入れてやればOK。





 …と言っても、自作関数である限り基本的には冒頭で書いた「リンカの初期値」が効いているはずなので、

どこかしらのライブラリから拝借してこないとまずは起こり得ないので、気にしなくてもいいといえばいいんだけど…。


 ちなみに、無理やりキャストしてやることも可能だけど、

呼び出し時等にランタイムエラー(?)が発生したりして、落ちます。

なので、関数ポインタか呼び出す元の関数の型を合わせてやりませふ。





 <<おまけ>>

 で、「呼び出し規約」って何が違うのよ?というわけで、

僕が知っている範囲でメモ。

(昔調べたり、うろ覚えだったりの適当加減なので、

あくまでも「そうなんだぁ。」位でお願いします(何))

・__stdcall … スタックの解放は呼ばれた側

・__cdecl … スタックの解放は呼ぶ側

・__fastcall … 引数x2までレジスタに格納(それ以上だったりしたら、__stdcallと同等)

そんな感じだったかと。

 「参考文献」

「__stdcallと__cdecl」

MSDN

…あれ?__fastcallの記述は確かMSDNかどこかだと思ったけど、微妙に違うな…どこで見たんだったかな…。