MyException - 我的异常网
当前位置:我的异常网» VC/MFC » 怎么同时兼容_cdecl,stdcall约定函数的调用

怎么同时兼容_cdecl,stdcall约定函数的调用

www.MyException.Cn  网友分享于:2013-04-03  浏览:62次
如何同时兼容__cdecl,__stdcall约定函数的调用
VC++程序调用约定指定为 __cdecl 则调整用 自己编写的__stdcall 约定DLL函数出现调用类型不匹配错误.

如何使程序可以用同一种方式调用两种不同的调用规则函数?

------解决方案--------------------
C#的delegate有这种功能,C++还是算了吧,如果你想做到这个,还不如想办法研究一下函数对象和模板。

------解决方案--------------------
不行,使用#ifdef吧
------解决方案--------------------
任何程序都可以同时使用这两种约定,实际上大家每天都这么做,因为一般你缺省的C程序时cdecl而windowsapi都时stdcall的。
你之所以不匹配是你声明的函数原型没有正确的说明你的调用约定是哪种类型的。所以可能你的dll里用stdcall调用,而实际你函数原型声明中并没有指明这一点。
引用楼主 smallfishff 的帖子:
VC++程序调用约定指定为 __cdecl 则调整用 自己编写的__stdcall 约定DLL函数出现调用类型不匹配错误.

如何使程序可以用同一种方式调用两种不同的调用规则函数?

------解决方案--------------------
探讨
道理知道的.只是想知道有没有什么方法能使用同种方式调用两种不同约定的函数.
C++中即可调用库函数的__cdecl 也可同时调用WIN32API的__stdcall 函数.内部会怎样处理呢?

------解决方案--------------------
不能直接支持。简单说来__stdcall堆栈是函数内部平衡,__cdecl是外部平衡。

_stdcall函数编译器生成 
Assembly code

push xx;
....
call XXFun;

------解决方案--------------------
可以,写成不带参数的函数就行。
------解决方案--------------------
DLL中的函数,只能用__cdecl 或__stdcall其中的一种。 
如果你要制作开发DLL,并且县对应两种参数处理方式,最好用类似下面这样宏定义。 
#define __mycall __cdecl 
//#define __mycall __stdcall 

在程序中只用 __mycall
------解决方案--------------------
是不是这样?如

typedef char* (WINAPI *MYFUNC)(char*, char*);
MYFUNC mystrcpy = NULL;

if(...)
mystrcpy = (MYFUNC)strcpy; // C库
else
mystrcpy = (MYFUNC)lstrcpyA; // API

char A[10];
char B[10];
__asm PUSH ESP; // 不管,自行平衡堆栈
mystrcpy(A, B);
__asm POP ESP;
------解决方案--------------------
探讨
引用:
为什么?!如果你知道自己dll中是什么方式调用,你可以用任何调用,为什么必须限制唯一性?你完全可以一个函数使用c调用,一个使用stdcall
为什么需要自己去搞这个?他是stdcall你就按stdcall调用,他是cdecl调用,你就按照cdecl调用,为什么会需要特殊处理?问题到底在哪?不明白你们到底在研究什么


那这样的话还是需要加上判断处理.如果需要代码重复或两种处理方式的话这并不是问题.
我所…

------解决方案--------------------
或者手动使堆栈平衡。
cdecl的函数,用stdcall调用完毕,可以加一句汇编add esp,x,x为所有参数占的空间大小
stdcall的函数,用cdecl调用完毕,可以加一句汇编sub esp,x,x为所有参数占的空间大小
------解决方案--------------------
先保存bsp,调用后恢复,可以不用管是那种调用方shi
------解决方案--------------------
#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;
}

文章评论

5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
程序员和编码员之间的区别
程序员和编码员之间的区别
我是如何打败拖延症的
我是如何打败拖延症的
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
编程语言是女人
编程语言是女人
代码女神横空出世
代码女神横空出世
漫画:程序员的工作
漫画:程序员的工作
总结2014中国互联网十大段子
总结2014中国互联网十大段子
 程序员的样子
程序员的样子
Java程序员必看电影
Java程序员必看电影
鲜为人知的编程真相
鲜为人知的编程真相
为什么程序员都是夜猫子
为什么程序员都是夜猫子
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
程序员都该阅读的书
程序员都该阅读的书
每天工作4小时的程序员
每天工作4小时的程序员
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
旅行,写作,编程
旅行,写作,编程
如何成为一名黑客
如何成为一名黑客
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
一个程序员的时间管理
一个程序员的时间管理
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
我的丈夫是个程序员
我的丈夫是个程序员
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
程序员的鄙视链
程序员的鄙视链
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
老程序员的下场
老程序员的下场
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
那些争议最大的编程观点
那些争议最大的编程观点
中美印日四国程序员比较
中美印日四国程序员比较
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有