首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

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

2012-04-02 
如何同时兼容__cdecl,__stdcall约定函数的调用VC++程序调用约定指定为 __cdecl 则调整用 自己编写的__stdc

如何同时兼容__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;
}

热点排行