函数调用规则主要是用于区别调用时的两个调用规约:
1、 函数参数的入栈方式;
2、 函数调用者还是函数本身还原栈。
规则有:stdcall、cdecl、fastcall、thiscall、nakedcall
__stdcall
1、 函数参数的入栈方式是最右边先入栈。
2、 调用者负责栈的回收。
3、 函数名编译后的生成规则是:_函数名@要还原的栈空间大小。
注意要点:
1、在Windows程序中,回调函数必须遵循__stdcall调用约定,所以我们在声明回调函数时要使用CALLBACK。使用CALLBACK而不是__stdcall的原因是为了告诉我们这是一个回调函数。注意,在Windows 98和Windows 2000下,声明窗口过程函数时,即使不使用CALLBACK也不会出错,但在Windows NT4.0下,则会出错。
__cdecl
1、 从右至左的顺序压参数入栈。
2、 由调用者把参数弹出栈,这样可实现参数个数可变,如printf函数。
3、 函数名编译后的生成规则是:_函数名。
注意要点:
1、 _cdecl是C和C++程序的缺省调用方式。
2、每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。
3、在VC++开发环境中,默认的编译选项是__cdecl,对于那些需要__stdcall调用约定的函数,在声明时必须显式地加上__stdcall。
__ fastcall
fastcall调用约定和stdcall类似,它意味着:
函数的第一个和第二个DWORD参数(或者尺寸更小的)通过ecx和edx传递,其他参数通过从右向左的顺序压栈被调用函数清理堆栈
函数名修改规则同stdcall
其声明语法为:intfastcall function(int a,int b)
__thiscall
对于参数个数固定情况下,它类似于stdcall,不定时则类似cdecl
生成动态库:
创建win32控制台项目,在应用程序设置向导中选中DLL选项,如图:
或者在工程中设置:
项目à属性à配置属性(常规)à配置类型,选择动态库(.dll)即可。F7会生成lib和dll文件,(揣测)lib是函数定位用的,编译后生成可执行文件,改可执行文件可以脱离lib文件运行,只需要dll文件。
在别人的代码中有添加这样的代码:
#define CCL_DLL_EXPORT
#ifdef CCL_DLL_EXPORT
#define CCL_API __declspec(dllexport)
#else
#define CCL_API
#endif
或者在工程中加入.def文件,然后添加类似的代码:
LIBRARY
EXPORTS
Test
我在测试过程中,不需要以上的添加方式也能正常生成lib文件和dll文件,是因为我的工程缺省使用cdecl调用方式(如果我目的就是使用cdecl调用方式)