函数调用约定

本文详细介绍了C/C++中的三种函数调用约定:_stdcall、_cdecl和_fastcall。_stdcall是Windows API的默认约定,参数从右到左压栈,函数返回前清栈。_cdecl则是C/C++的默认约定,调用者负责清栈。_fastcall通过寄存器传递参数,提高效率。函数调用约定不匹配可能导致堆栈异常,而名字修饰规则不匹配则可能在链接时出错。解决方法包括确保调用约定一致,并使用extern "C"来避免C++的名字修饰。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考博客:http://blog.youkuaiyun.com/qinmi/article/details/1744951

(1)_stdcall调用  _stdcallPascal程序的缺省调用方式,参数采用从右到左的压栈方式,被调函数自身在返回前清空堆栈。大多数WIN32Api都采用了_stdcall调用方式。如果按C编译方式(除非另外重新指定编译方式,否则编译器会根据源文件的扩展名选择编译方式,如果文件的扩展名是“.C”,编译器会采用C的语法编译,如果扩展名是“.cpp”,编译器会使用C++的语法编译程序)_stdcall调用约定会在输出函数名前面加下划线,后面加“@”符号和参数的字节数,形如_functionname@bytes。例如有如下整型相加函数add,头文件add.h中声明如下:

#define DLL_EXPORTS
//vs2010新建dll时,如果勾选“导出符号”选项,则会自动填充下面的宏定义代码,并且会自动define DLL_EXPORTS,以使得宏定义执行#define DLL_API __declspec(dllexp//ort),但勾选“导出符号”默认生成的是.cpp文件,此处我们需要用.c文件来生成dll,因此新建dll时不需勾选“导出符号”,但为了dll文件中的函数被声明为导出类型,///因此这里需加入#define DLL_EXPORTS,当将dll和.h文件给其他人调用时,将#define DLL_EXPORTS注释掉,以使得宏定义执行#define DLL_API __declspec(dllimport) 
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif

DLL_API int _stdcall add(int,int);   //声明_stdcall调用约定

对应的add.c文件中有:

#include "add.h"
 
DLL_API int _stdcall add(int a ,int b)
{
    return a+b;
}

下面是指定_stdcall调用,按c方式编译时函数名的修饰(用Dependency查看):

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值