是否存在标准调用约定
Do standard calling conventions exist?
我最近在custm CALLBACK的函数指针方面遇到了问题,这归结为使用调用约定来暂时解决问题,当时funy CALLBACK确实工作得很好,但调用函数的签名仍然是错误的!!我花了很多时间找到BUG。意识到caling惯例有时会让你做一些不好的事情。。。
好吧,现在已经过去了。。。现在,我想了解更多关于调用约定的信息: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寄存器错误。
否;调用约定是特定于平台的。前导双下划线表明这是一个保留实现的概念。语言本身对如何在这个细节级别上实现它没有任何要求。
在没有__cdecl的情况下崩溃的原因是因为Windows编译器默认使用__stdcall。后者强制被调用方函数清理堆栈。因此,您的调用方将两个参数推到堆栈上以调用"Trigger",但Trigger在函数退出时仅从堆栈中弹出一个参数。因此,你崩溃了__cdecl调用约定可以绕过这一点。
正如我在上面的评论中所说,使用__cdecl来修复崩溃隐藏了真正的错误。触发器的参数列表与"MethodHandler"所需的参数列表不匹配。这很可能是你撞车的原因。
这可能是一个更好的解决方案:
typedef void(Object::*MethodHandler)(Object* sender, EventArgs args);
void Triger(Object* sender, EventArgs args)
{
if(args == "test")
cout << "test args received" << endl;
}
您没有分享显示"触发器"如何为后续回调注册的代码。但我强烈怀疑你投下了这样的东西:
MethodHandler handler = (MethodHandler)Trigger;
因为如果你不这样做,你的代码就不会编译。修复你的代码,这样编译就不需要强制转换了,你真正的bug和崩溃都会消失。
- 为什么在 x64 中忽略__stdcall调用约定?
- 窗口调用约定
- 我应该提到纯虚函数中的调用约定吗?
- 如何使用gcc指定stdcall调用约定
- Clang:x86 FPU调用约定
- 该标准是否说明了例外和不同调用约定的共存
- Clang++的InterlockedExchange的32位调用约定错误,但MSVC可以
- std::sort & comp - 调用约定?
- 如何为类 /块 /范围选择C 调用约定
- DLL 的"good"调用约定是什么?
- 结构中重载运算符的调用约定
- 'ShowSUM':__declspec(dllexport)不能应用于具有__clrcall调用约定的函数
- x86-64 调用约定中的返回值
- 内联功能和调用约定
- 正在直接显示筛选器中调用约定
- 何时使用`__fastcall`调用约定
- 为C++结构定义显式析构函数如何影响调用约定
- 对类方法的正确约定调用
- 如何使用 Visual C++ 中的 Delphi 寄存器调用约定调用函数?
- 使用C调用约定调用函数模板专门化