私は最近custm CALLBACKの関数ポインタに問題があり、問題を一時的に解決する呼び出し規約を使用するようになった。funy CALLBACKはうまくいったが、呼び出し関数のシグネチャはまだ間違っていた!!そのBUGを見つけるのに多くの時間を費やしました。 がcaling規則はあなたが時々OKではない何かに何かをやらせることに気づいた...今までだ標準の呼び出し規約が存在しますか?
OKは...今、私は、呼び出し規約についてlitleもっと知りたい: Visual Studioは、それは__cdecl
自分のしています、 __thiscall
など(IIRC)。
標準のC++ではいくつかの呼び出し規約が規定されていますが、どうすれば使えますか?
編集:私はバグ見つけることができませんでしたいくつかのコードれている:
class Object;
class EventArgs;
typedef void(__cdecl Object::*MethodHandler)(Object* sender, EventArgs args);
///..... this is how I call it..(snapshot)
(iter->second.sender->*iter->second.memberFunct)(sender, args);
///...
void __cdecl Triger(EventArgs args) //missing "Object* sender" here!!! but it works!
{
if(args == "test")
cout << "test args received" << endl;
}
を(。ところで、タイプ名は私のカスタムクラスである)うまく働いた !関数が呼び出されましたが、__cdecl
がないと、私はESPレジスタエラーを受け取りました。
バグは何ですか?通常、コンパイラエラーなしでハンドラ/コールバックを登録するための関数ポインタのハードコーディングされたキャストは、何か間違ったことをしている間違いです。上記のコードでは、関数の引数が異なるため、 "Trigger"はMethodHandler型ではありません。 – selbie
ありがとうございます、それは同じ署名ではありませんが、私は__cdeclを使用しない場合、__cdelcを使用してうまく動作し、ESPの登録エラーとprogrm chrush ..非常に興味深い.. – codekiddy
あなたは幸運を得ているので引数がスタックにプッシュされる順序に変更します。 cdeclのトリックはおそらくちょうどそれがクラッシュしないようにスタックをマッサージしています。あなたのコードのどこかで、コンパイルエラーなしでその関数をコールバックサービスに登録するために、 "(MethodHandler *)Trigger"(またはvoid *キャスト)を行っています。コードを修正して、コードをキャストなしでコンパイルすると、クラッシュが消えてしまいます。これはどこでも同じ呼び出し規約と同じ引数リストを意味します。 – selbie