C/C++函数调用约定之间的转换
C语言的初学者常犯的一个失误是调用系统或第三方API时忘了在函数声明中标注WINAPI调用方式,而菜鸟C++程序员也每每困惑为什么成员函数必须指示为CALLBACK再添加static关键字才能作为回调函数。在x86系统中,存在多种函数调用约定。如果调用者与被调用者采用不同的调用约定,很可能导致堆栈破坏、非法访问等致命错误。
也许您会得出一个结论,除非借助汇编指令,否则调用约定之间的转换是不可能的。不过很多事情都不是绝对的。我们先看下面的例子:
#include
int __cdecl CDeclFunction()
{
printf("from CDecl function\n");
return 1;
}
int main()
{
printf("Begin call STDCall function\n");
typedef int(__stdcall * STDCALLFUNCTION)();
STDCALLFUNCTION pfn =(STDCALLFUNCTION)CDeclFunction;
int i=pfn();
printf("End call STDCall function\n");
return i;
}
这是一个简单的函数调用的例子,唯一特别的地方是函数定义为__cdecl,而调用时采用__stdcall方式。我们把这段代码编译后执行。嗬,一切正常。如果您不服气,再加一个for循环看看J
我们再来看另一个更特别的例子:
#include
int __stdcall StdCallFunction (int i, char* pszString)
{
printf("from STDCall function\n");
printf(pszString);
return i;
}
int main()
{
printf("Begin call FastCall function\n");
typedef int(__fastcall * FASTCALLFUNCTION)(int, int, int, char*);
FASTCALLFUNCTION pfn =(FASTCALLFUNCTION)StdCallFunction;
int i=pfn(0,0,3,"test\n");
printf("End call FastCall function\n");
return i;
}
这次不光调用方式不同,连参数的个数都不一样。别担心,我们编译后执行。还是一切正常!
如果您对上述两个例子百思不得其解的话,现在该是解开谜底的时候了。这个谜底就是函数调用约定本身。网上介绍调用约定的资料已经相当多了,不过几乎都侧重比较各种调用方式的差别,而本文将把重点放在这些调用方式之间的联系上面(这里也略去诸多与主题无关的细节,要想了解函数调用约定的所有方式,相应的汇编代码,以及在参数或返回值超过32位等复杂情况的处理方式,请查阅本文列出的参考书目)。
调用函数时,需要传递参数,并接收返回值。对于C++ 非静态成员函数,还要考虑如何传递this指针。这要么采用寄存器,要么采用堆栈。如果采用堆栈,还要考虑由谁负责恢复堆栈的平衡。调
相关文档:
/*FIXME
ISO C如果你在main()中写代码的中间定义了一个对于main而言的全局变量,就会报出这个错误。
*/
把这个变量定义到main函数中的最前方,就会修正这个错误。
而且为了防止出错,设定的指针之后再有参数传入malloc之后立即对于指针予以空间的创建。防止出现指针未初始化从而引起将来赋值的时候将该值覆盖了已经为本 ......
原帖:
http://hi.baidu.com/pepsi360/blog/item/cc74be4412cf6789b3b7dcd4.html
#include <stdio.h>
struct Node
{
int a;
char b[10];
Node *next;
};
main(void)
{
char *p=NUL ......
在这儿下载:color-theme
:
http://download.savannah.gnu.org/releases-noredirect/color-theme/
wget http://download.savannah.gnu.org/releases-noredirect/color-theme/color-theme-6.6.0.tar.gz
tar zxf color-theme-6.6.0.tar.gz -C ~/.emacs.d
在.emacs中加入下列语句:
;; corlor-theme ......
http://www.mathworks.com/access/helpdesk/help/techdoc/apiref/mexfunction.html
mexFunction (C and Fortran) -
Entry point to C/C++ or Fortran MEX-file
C Syntax
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs,
const mxArray *prhs[]);
Fortran
Syntax
subrouti ......