简介
一般在写动态链接库时,都要指定动态库中接口函数的调用约定,如windows中系统函数常用的调用约定通常是:WINAPI。实际上WINAPI就是stdcall的重定义。
在C语言中,函数常用的调用约定包含如下2种:
- cdecl
- stdcall
其他还有fastcall等约定,一般不常用。
调用约定
所谓调用约定,就是指函数提供者与函数使用者之间使用相同的顺序对函数参数、返回值等进行入栈、出栈。如果函数提供者与函数使用者使用不同的顺序进行参数的入栈出栈,大概率函数不能正确执行,甚至可能会引起程序崩溃。
linux下设置函数调用约定
int attribute((stdcall)) funcname()
int attribute((cdecl)) funcname()
如果在定义函数时,不指定函数的调用约定,则函数默认的定义为:
int attribute((cdecl)) funcname()
例子
/* 函数提供者提供的add函数
使用了stdcall的方式指定了调用约定,
则编译器在编译的时候按照stdcall的约定,将参数a和b从堆栈取出。
*/
int __attribute__((__stdcall__)) add(int a, int b)
{
return a + b;
}
/*函数使用者在使用add的时候,需要按照调用约定声明函数,然后才能调用
函数。
如果不进行正确声明,这函数使用者的编译器会按默认的cdecl方式调用add函数,可能会导致函数不正常。
*/
int __attribute__((__stdcall__)) add(int a, int b);
int c = add(100, 200);
完!