简体   繁体   中英

Do standard calling conventions exist?

I've recently having problems with custm CALLBACK's function pointers, and that boiled down into using calling conventions which solve the problem temporaly, funy CALLBACK did work well then but signature of the calling function was still misstyped!! and I've spend a lot of time finding that BUG out. realized that caling convention let you do something what isn't OK sometimes...

OK that's past now... Now, I want to know a litle more about calling conventions: Visual Studio has it's own __cdecl , __thiscall , etc (IIRC).

Does standard C++ regulates some calling conventions and how can I use them if so?


EDIT: Some code on which I failed to find a bug :

    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;
    }

(BTW, type names are my custom classes.) That worked just fine! Function was called but without __cdecl I have received ESP register errors.

No; calling conventions are platform specific. The leading double underscore is a clue that this is an implementation-reserved concept. The language itself makes no requirements about how it is to be implemented at this level of detail.

The reason why you crash without __cdecl is because the Windows compiler default is to use __stdcall. The latter forces the callee function to cleanup the stack. Hence, your caller is pushing two arguments on to the stack to invoke "Trigger", but Trigger is only popping one argument off the stack on function exit. Hence, you crash. __cdecl calling convention kind of gets around this.

As I said in my comments above, using __cdecl to fix the crash is hiding the real bug. Your argument list of trigger is not matching the argument list expected of "MethodHandler". That's likely the cause of your crash.

This is likely a better fix:

typedef void(Object::*MethodHandler)(Object* sender, EventArgs args);

void Triger(Object* sender, EventArgs args)
{
    if(args == "test")
    cout << "test args received" << endl;
}

You didn't share the code that shows how "Trigger" gets registered for a subsequent callback. But I strongly suspect you have put a cast of something like this:

MethodHandler handler = (MethodHandler)Trigger;

Because if you didn't do that, your code didn't compile. Fix your code such that the cast isn't needed for compile, and your real bug goes away as well as your crash.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM