如何同时兼容__cdecl,__stdcall约定函数的调用

smallfishff 2009-07-07 03:37:35
加精
VC++程序调用约定指定为 __cdecl 则调整用 自己编写的__stdcall 约定DLL函数出现调用类型不匹配错误.

如何使程序可以用同一种方式调用两种不同的调用规则函数?
...全文
416 44 打赏 收藏 转发到动态 举报
写回复
用AI写文章
44 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhengguoying 2010-04-22
  • 打赏
  • 举报
回复
路过啊实施上述事实上述事实上述事实上
做鸡真好吃 2009-08-21
  • 打赏
  • 举报
回复
mark~
cadhy 2009-07-10
  • 打赏
  • 举报
回复

mark
clever101 2009-07-10
  • 打赏
  • 举报
回复
学习!
smallfishff 2009-07-10
  • 打赏
  • 举报
回复
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
sunlin7 2009-07-10
  • 打赏
  • 举报
回复
#include <stdlib.h>
int __cdecl func1(int a, char b)
{
return 0;
}

int __stdcall func2(int a, char b)
{
return 0;
}

int main(int argc, char **argv)
{
__asm
{
pushad;
mov ebp, esp; // 保存esp,cdecl 与stdcall是最大差别是谁清栈,这里不管谁清栈都恢复到调用前的栈
push 0;
push 0;
call func1;
call func2;
mov esp, ebp;
popad
}
return 0;
}
zwh50687695 2009-07-09
  • 打赏
  • 举报
回复
mark
greatws 2009-07-09
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 smallfishff 的回复:]
调用时就会报调用不一致错误.
[/Quote]
你说的错误指什么?
zoulie 2009-07-09
  • 打赏
  • 举报
回复
看看罗老大的win32 汇编
zoulie 2009-07-09
  • 打赏
  • 举报
回复
自己写ASM代码,进行压栈与恢复堆栈平衡
smallfishff 2009-07-09
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 greatws 的回复:]
或者手动使堆栈平衡。
cdecl的函数,用stdcall调用完毕,可以加一句汇编add esp,x,x为所有参数占的空间大小
stdcall的函数,用cdecl调用完毕,可以加一句汇编sub esp,x,x为所有参数占的空间大小
[/Quote]

调用时就会报调用不一致错误.

[Quote=引用 32 楼 arong1234 的回复:]
还是不明白你为什么需要判断啊?!每个函数你严格知道他的函数原型(如果你不知道函数原型就调用是非常不合理的),那么既然知道函数原型,你就知道他的调用约定,你为什么还需要去判断他调用约定是什么?!

函数在编译成汇编的时候就确定调用模式了,不明白楼主要干什么?如果函数定义和调用类型不一致,编译器会自动KAXX的
[/Quote]

为什么不知道就非常不合理?
例如程序有一个接口 可以调用某个函数.但这个函数由外部程序编写 不清楚它的函数调用方式.然后需要用一个统一的方式去处理它 这就办不到了.所以还是需要先判断这个外部函数的调用方式是哪种 然后程序再根据这个判断来使用不同的处理方式来调用.

[Quote=引用 32 楼 arong1234 的回复:]
函数在编译成汇编的时候就确定调用模式了,不明白楼主要干什么?如果函数定义和调用类型不一致,编译器会自动KAXX的
[/Quote]

外部函数本身是已编译好固定不变了没错 但我调用者可以根据它的函数调用约定来判断使用不同的调用方式吧...
pady_pady 2009-07-09
  • 打赏
  • 举报
回复
函数在编译成汇编的时候就确定调用模式了,不明白楼主要干什么?如果函数定义和调用类型不一致,编译器会自动KAXX的
stjay 2009-07-08
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 arong1234 的回复:]
为什么需要自己去搞这个?他是stdcall你就按stdcall调用,他是cdecl调用,你就按照cdecl调用,为什么会需要特殊处理?问题到底在哪?不明白你们到底在研究什么
[/Quote]

我也不明白LZ想怎样,只是举个例

或者对调用动态加载DLL的函数时有用

或者调用回调函数之类的

或者HOOK方面
na_he 2009-07-08
  • 打赏
  • 举报
回复
study..
oyljerry 2009-07-08
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 smallfishff 的回复:]
引用 18 楼 arong1234 的回复:
为什么?!如果你知道自己dll中是什么方式调用,你可以用任何调用,为什么必须限制唯一性?你完全可以一个函数使用c调用,一个使用stdcall
为什么需要自己去搞这个?他是stdcall你就按stdcall调用,他是cdecl调用,你就按照cdecl调用,为什么会需要特殊处理?问题到底在哪?不明白你们到底在研究什么


那这样的话还是需要加上判断处理.如果需要代码重复或两种处理方式的话这并不是问题.
我所…
[/Quote]
最好用统一的调用约定,不同样的话,你Debug版本调试时,编译器会提示你的call conversion不一致,直接中断了
sunlin7 2009-07-08
  • 打赏
  • 举报
回复
懂汇编就好办啊,__stdcal 与__cdecl的区别在于是被调用者清栈还是调用都清栈。
smallfishff 2009-07-08
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 arong1234 的回复:]
为什么?!如果你知道自己dll中是什么方式调用,你可以用任何调用,为什么必须限制唯一性?你完全可以一个函数使用c调用,一个使用stdcall
为什么需要自己去搞这个?他是stdcall你就按stdcall调用,他是cdecl调用,你就按照cdecl调用,为什么会需要特殊处理?问题到底在哪?不明白你们到底在研究什么
[/Quote]

那这样的话还是需要加上判断处理.如果需要代码重复或两种处理方式的话这并不是问题.
我所需要的只是想知道能不能使用同一种调用方法来调用两个不同的约定....不是讨论它本质的区别与原理.这个我都明白.
看来只能是根据判断来使用不同的调用方法分别来处理__cdecl和__stdcall了.

[Quote=引用 greatws 的回复:]
可以,写成不带参数的函数就行。
[/Quote]

的确之前我试过不带参数的任何约定调用都可行.
arong1234 2009-07-08
  • 打赏
  • 举报
回复
还是不明白你为什么需要判断啊?!每个函数你严格知道他的函数原型(如果你不知道函数原型就调用是非常不合理的),那么既然知道函数原型,你就知道他的调用约定,你为什么还需要去判断他调用约定是什么?!
[Quote=引用 23 楼 smallfishff 的回复:]
引用 18 楼 arong1234 的回复:
为什么?!如果你知道自己dll中是什么方式调用,你可以用任何调用,为什么必须限制唯一性?你完全可以一个函数使用c调用,一个使用stdcall
为什么需要自己去搞这个?他是stdcall你就按stdcall调用,他是cdecl调用,你就按照cdecl调用,为什么会需要特殊处理?问题到底在哪?不明白你们到底在研究什么



那这样的话还是需要加上判断处理.如果需要代码重复或两种处理方式的话这并不是问题. …
[/Quote]
sunlin7 2009-07-08
  • 打赏
  • 举报
回复
先保存bsp,调用后恢复,可以不用管是那种调用方shi
fayn6367 2009-07-08
  • 打赏
  • 举报
回复
不明白
加载更多回复(23)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧