_stdcall,_cdecl代表什么?(50分)

  • 主题发起人 主题发起人 huxiaoxuan
  • 开始时间 开始时间
H

huxiaoxuan

Unregistered / Unconfirmed
GUEST, unregistred user!
vc里面在函数声明时经常看到_stdcall,_cdecl,代表什么?
 
指示该函数的调用方式,比仿说你上面说的那两个是标准C语言的呼叫方式。
 
具体是什么意思??
 
包括参数的传递顺序和方式,谁负责释放参数的栈。
C++还有“名字粉碎”
__cdecl Specifics
For C, the __cdecl naming convention uses the function name preceded by an underscore ( _ );
no case translation is performed. Unless declared as extern "C", C++ functions use a different name-decorating scheme. For more information on decorated names, see Decorated Names.
__fastcall Specifics
Some of a __fastcall function’s arguments are passed in registers x86 Specific —> ECX and EDX END x86 Specific, and the rest are pushed onto the stack from right to left. The called routine pops these arguments from the stack before it returns. Typically, /Gr decreases execution time.
Important Be careful when using the __fastcall calling convention for any function written in inline assembly language. Your use of registers could conflict with the compiler’s use.
For C, the __fastcall naming convention uses the function name preceded by an at sign (@) followed by the size of the function’s arguments in bytes. No case translation isdo
ne. The compiler uses the following template for the naming convention:
@function_name@number
Note Microsoftdo
es not guarantee the same implementation of the __fastcall calling convention between compiler releases. For example, the implementation differs between the 16-bit and 32-bit compilers.
When using the __fastcall naming convention, use the standard include files. Otherwise, you will get unresolved external references.
__stdcall Specifics
A __stdcall function’s arguments are pushed onto the stack from right to left, and the called function pops these arguments from the stack before it returns.
For C, the __stdcall naming convention uses the function name preceded by an underscore ( _ ) and followed by an at sign (@) and the size of the function’s arguments in bytes. No case translation is performed. The compiler uses the following template for the naming convention:
_functionname@number
x86 Specific —>This option has no effect on the name decoration of C++ methods and functions. Unless declared as extern "C", C++ methods and functions use a different name-decorating scheme. For more information on decorated names, see Decorated Names. END x86 Specific
 
到底什么时候需要用这些修饰符呢?看别人写dll的时候好像经常用到,为什么
 
调用其它语言编写的DLL时会用到,调用规则必须和它一样。
这时一般是 _stdcall,也可能是其它. 因为其它语言也能指定调用规则.
 
_cdecl,好像是让代码精简一些。不知理解对否?请批评指正。
 
我上次写dll的导出函数声明改为stdcall后,就无法导出了, 不知道为什么
代码:
还有,我用_cdecl声明的导出函数名和原来的函数名不一样,后面加了@@?...
有谁碰到过这种情况?
 
不同的语言相互调用必须指定调用方式
不指定的话,c缺省是用cdecl,pascal缺省使用pascal,就会调用失败
调用方式最主要是参数传递的问题
比如,
stdcall、cdecl传递参数,是从从右到左入栈,
比如 _stdcall f(a,b,c),参数是 push c、 push b、 push a 入栈的
pascal传递参数,是从从左到右入栈,
比如 pascal f(a,b,c),参数是 push a、 push b、 push c 入栈的
所以调用不同语言定义的函数,必须双方使用相同的调用方式,取出来的参数才和调用者给出的参数一致
另外,他们还有函数返回之后由谁清除堆栈的不同
stdcall是由 被调用者 清除堆栈的,调用者等待函数返回后,不用处理堆栈,直接可以进行其他处理
pascal、cdecl是由 调用者 清除堆栈的,调用者等待函数返回后,需要处理堆栈,比如把堆栈指针增加,或者
把原来push进去的参数pop出来,恢复堆栈到原来的状态,才可以进行其他处理
因为,stdcall、cdecl的参数入栈顺序和pascal不同
而stdcall和cdecl、pascal的清除堆栈的方式不同,所以这3种都不同,不能混用
而fastcall传递参数使用寄存器,更不一样了
 
多人接受答案了。
 
后退
顶部