DLL导出与调用约定
一般来说,从DLL导出函数有两种方法。一种是使用.def文件;另一种是使用__declspec(dllexport)。
使用上面两种方法各有优缺点。使用.def文件就是需要额外维护,当导出函数更改名字或者追加导出函数。而使用__declspec(dllexport)则需要注意使用的调用约定,在使用C++编译器时。
调用约定
在使用C++或者在常见的windows API的声明头文件常见的WINAPI,而WINAPA就是__stdcall。在C++还有__cdecl。而__pascal和__thiscall都已忽略了。宏PASCAL也用的是__stdcall。
一般来说,调用约定只关乎参数的压栈和最后的清理工作。还有就是名字修饰。比如:
void func(char, short, int, double)
使用__cdecl调用:

使用C编译器编译后的修饰名字为:_func。清理栈的工作由调用方做。
使用__stdcall和__thiscall调用:

使用C编译器编译后的修饰名字为_func@20。清理栈的工作由被调方做。
使用__fastcall调用:

使用C编译器编译后的修饰名字为@func@20。清理栈的工作由被调方做。
名字修饰
从上面的图也可看见,压栈都是从右到左,而名字修饰的方法却不一样。C编译器的修饰方法相对来说比较简单。以_func@20为例,_是追加的,func就是函数的名字,@是追加的,20为参数的字节数。C++的修饰方法相对来说比较复杂。下图是使用C++编译器产生的名字,使用__declspec(dllexport)和__stdcall。

下图是使用__cdecl编译:

大致一看都差不多,只是在名字后的有个字母不一样,__stdcall得是YG,而__cdecl的是YA。而这也正好指明了C++的名字修饰的规则,简单来说就是:
・名字(可以包含命名空间)
・调用约定
・返回值
・参数列表
调用约定修饰规则:
| 代号 | 调用约定 |
| @@YG | __stdcall |
| @@YA | __cdecl |
| @@YI | __fastcall |
类型修饰规则:
| 代号 | 含义 |
| X | void |
| D | char |
| E | unsigned char |
| F | short |
| H | int |
| I | unsigned int |
| J | long |
| K | unsigned long(DWORD) |
| M | float |
| N | double |
| _N | bool |
| U | struct |
| PA | pointer |
| PB | const pointer |
参数表后以”@Z”标示整个名字的结束,如果该函数无参数,则以”Z”标识结束。
最后一点:如果我们直接使用__declspec(dllexport)导出函数的话,最好使用C编译器。如果直接用C++编译器,导出的函数名就像上面一样。在动态使用DLL时调用GetProcAddress使用原始函数名称一般来说会失败。例如:
GetProcAddress(handle, "func");
所以一般使用C编译器,比如这样:
#ifdef __cplusplus // If used by C++ code
extern "C" { // we need to export the C interface
#endif __declspec(dllexport) VOID __cdecl func(char, short, int, double)
{
...
} #ifdef __cplusplus
}
#endif
这时,修饰后的名字就是这样:

一般导入函数时也建议这样:
#ifdef __cplusplus
extern "C" {
#endif // _declspec(dllimport) VOID func(char, short, int, double);
// or
VOID func(char, short, int, double); #ifdef __cplusplus
}
#endif
第一种写法在效率上来说会更好点。
参考:http://hi.baidu.com/luosiyong/item/c8664533f56b66c31b9696e3
http://msdn.microsoft.com/en-us/library/k2b2ssfy.aspx
DLL导出与调用约定的更多相关文章
- C/C++:函数的编译方式与调用约定以及extern “C”的使用
转自:https://www.cnblogs.com/qinfengxiaoyue/archive/2013/02/04/2891908.html 函数在C++编译方式与C编译方式下的主要不同在于:由 ...
- DLL中调用约定和名称修饰(一)
DLL中调用约定和名称修饰(一) 调用约定(Calling Convention)是指在程序设计语言中为了实现函数调用而建立的一种协议.这种协议规定了该语言的函数中的参数传送方式.参数是否可变和由谁来 ...
- 【原创+整理】简述何为调用约定,函数导出名以及extern C
何为调用约定 调用约定指的是函数在调用时会按照不同规则,翻译成不同的汇编代码.这和参数的压栈顺序和栈的清理方式相关,也就是说不同的调用约定,这些方式会做相应改变.一般编译器是以默认的调用约定编译一份代 ...
- C/C++/动态链接库DLL中函数的调用约定与名称修饰
参见:http://blog.twofei.com/cc/impl/calling-convension.html 调用约定(Calling Convention)是指在程序设计语言中为了实现函数调用 ...
- DLL导出函数和类的定义区别 __declspec(dllexport)
DLL导出函数和类的定义区别 __declspec(dllexport) 是有区别的, 请看 : //定义头文件的使用方,是导出还是导入 #if defined(_DLL_API) #ifndef D ...
- C++调用约定和名字约定
C++调用约定和名字约定 转自http://www.cppblog.com/mzty/archive/2007/04/20/22349.html 调用约定:__cdecl __fastcall与 __ ...
- dll 导出函数名的那些事
dll 导出函数名的那些事 关键字: VC++ DLL 导出函数 经常使用VC6的Dependency或者是Depends工具查看DLL导出函数的名字,会发现有DLL导出函数的名字有时大不相同,导 ...
- c++builder调用VC的dll以及VC调用c++builder的dll
解析__cdecl,__fastcall, __stdcall 的不同:在函数调用过程中,会使用堆栈,这三个表示不同的堆栈调用方式和释放方式. 比如说__cdecl,它是标准的c方法的堆栈调用方式,就 ...
- dll的概念 dll导出变量 函数 类
1. DLL的概念 DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数.变量或类.这些可以直接拿来使用. 静态链接库与动态链接库的区别: (1)静态链接 ...
随机推荐
- Android开发之Handler
我们都知道应用程序开启后,安卓会开启一个主线程(UI线程),主线程管理UI控件,进行事件分发.那为什么会出现Handler呢? 例如你要是点击一个 Button ,Android会分发事件到Butto ...
- 学习笔记7_Java_day11_JSP原理(5)
4. jsp原理(理解) * jsp其实是一种特殊的Servlet > 当jsp页面第一次被访问时,服务器会把jsp编译成java文件(这个java其实是一个servlet类) > 然后再 ...
- Swift 语法须知
什么是swift? swift是 2014 WWDC 发布的一款脚本语言. 使用Swift的好处: OC ARC 最大的困难 内存管理 而 swift 不用担心内存方面. 简洁 ,功能 ...
- PHP pear安装出现 Warning: require_once(Structures/Graph.php)...错误
今天在WINDOWS安装pear,一路无阻很顺利安装完成,接着想安装下pear email包来玩下,但接下来却报: Warning: require_once(Structures/Graph.php ...
- VMware Workstation不能启用虚拟设备floppy0由于灭有相应的有效设备在主机上. 你要尝试在每次打开虚拟机电源时连接此虚拟设备?
编辑虚拟机的硬件,把软盘取消掉,floppy的提示就没有了
- Mantle 简单教程
Mantle可以很方便的去书写一个模型层的代码. 使用它可以很方便的去反序列化JSON或者序列化为JSON(需要在MTLModel子类中实现<MTLJSONSerializing>协议) ...
- 网站前端优化 -saveForSelf
九.网站前端优化 – IMG 9.1.可以优化的图片 图片总共可以分为两类,一个是CSS IMAGES,另一个是产品图片. 9.2.CSS IMAGES CSS图片现在采用的方式是图片合并的方式,这样 ...
- ubuntu基本操作(2)
查看当前使用那种 shell echo $SHELL 更换 shell 类型:首先检查是否安装了相应的类型 shell开启终端,直接输入相应的 shell 名称如果没有安装,则先安装,否则直接启动此时 ...
- H5小内容(三)
Canvas(画布) 基本内容 简单来说,HTML5提供的新元素<canvas> Canvas在HTML页面提供画布的功能 在画布中绘制各种图形 C ...
- css中 中文字体(font-family)的标准英文名称
Mac OS的一些: 华文细黑:STHeiti Light [STXihei] 华文黑体:STHeiti 华文楷体:STKaiti 华文宋体:STSong 华文仿宋:STFangsong 儷黑 Pro ...