使用def文件简化dll导出
原文链接地址:http://www.cnblogs.com/TianFang/archive/2013/05/04/3059073.html
在C++中,我们可以通过 __declspec(dllexport) 将函数导出为Dll中供其它程序使用,例如:
_declspec(dllexport) int add(int a, int b);
在这种方式下,如果调用该dll的是一个c++程序(同一个编译器的版本)是没有问题的。但是,如果调用该dll是一个其它语言的程序(如C#、VB),则会出错。究其原因,是因为在C++中存在函数的重载,允许函数重名,因此在编译器生成dll的时候,为了区别重名的程序,会将其进行一定算法进行名称转换。例如,对于前面的add函数,实际的函数名称是如下形式。

因此,我们直接通过函数名add是无法找到该函数的,从而导致调用失败。为了解决这一问题,我们往往在函数前面再加一个extern "C",使用C方式的函数命名规则。
extern "C" _declspec(dllexport) int add(int a, int b);
这样函数的名称就成add了。

这样,我们就需要在每一个函数签名加上"extern "C" _declspec(dllexport)"这一长串声明。如果需要导出的函数较多则显得非常繁琐,也非常难看。为了简化这一过程,MS引入了def文件方便我们操作。
使用Def文件比较简单,只需要在项目中添加一个def文件,然后把我们要导出的函数放在def文件中即可。

Def文件的简单示例如下:
LIBRARY
EXPORTS
add
最后记得在链接器选项中选中使用的def文件(默认情况下,添加def文件时会自动加上该选项,无需手动更改)。

这样,我们的函数无需加那一堆前缀,仍然可以使用默认的int add(int a, int b);形式,但导出后的方式依然是C形式的函数定义。

最后指得一提的是,一般C/C++默认的调用方式是__cdecl,这种方式下需要调用方对函数清栈。如果对外提供api共其它非C++程序使用时,调用方会无法清栈而出错(C#会直接报函数声明不匹配的错误)。因此,对外提供api时还应该将接口声明为__stdcall,让api函数自己清栈。这也是Windows API前面都加上了一个WINAPI的宏的原因。
def文件还有许多其它的高级用法,要进一步了解的话,可以参看一下MS的官方文档:http://msdn.microsoft.com/zh-cn/library/28d6s79h(v=vs.80).aspx
使用def文件简化dll导出的更多相关文章
- VC2010 利用 def 文件生成 dll 文件的方法
近期有个需求,要生成一个dll 文件.文件里的函数都是採用 stdcall 函数调用约定,可是不希望函数名被修饰(add 被修饰成 add@8). 这时就要用def 文件了. 比方我有以下两个函数: ...
- DLL导出函数
使用DEF文件从DLL导出 模块定义(.def)文件时包含一个或多个描述DLL各种属性的Module语句的文本文件.如果不使用_declspec(dllexport)关键字导出DLL的函数,则DLL需 ...
- DLL中导出函数的两种方式(dllexport与.def文件)
DLL中导出函数的声明有两种方式: 一种方式是:在函数声明中加上__declspec(dllexport): 另外一种方式是:采用模块定义(.def)文件声明,(.def)文件为链接器提供了有关被链接 ...
- (转)DLL中导出函数的两种方式(dllexport与.def文件)
DLL中导出函数的两种方式(dllexport与.def文件)http://www.cnblogs.com/enterBeijingThreetimes/archive/2010/08/04/1792 ...
- 【转】DLL中导出函数的两种方式(dllexport与.def文件)
DLL中导出函数的两种方式(dllexport与.def文件) DLL中导出函数的声明有两种方式: 一种方式是:在函数声明中加上__declspec(dllexport):另外一种方式是:采用模块定义 ...
- 简单了解 DLL中, .def 文件及C#调用C++方法
DLL中导出函数的声明有两种方式: 1.在函数声明中加上__declspec(dllexport) //以下内容为 .h 文件中的内容 //向外界提供的端口 extern"C" _ ...
- c++ exports def文件
https://msdn.microsoft.com/zh-cn/library/hyx1zcd3(v=vs.80).aspx EXPORTS 引入了一个由一个或多个 definitions(导出的函 ...
- 详解模块定义(.def)文件
一个完整的Windows应用程序(C++程序)通常由五种类型的文件组成:源程序文件,头文件,资源描述文件,项目文件,模块定义文件.本文主要讲解模块定义文件. 模块定义 (.def)文件为链接器提供有关 ...
- dll的概念 dll导出变量 函数 类
1. DLL的概念 DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数.变量或类.这些可以直接拿来使用. 静态链接库与动态链接库的区别: (1)静态链接 ...
随机推荐
- python网络编程,通过服务名称和会话类型(tcp,udp)获取端口号,简单的异常处理
作为一个php程序员,同时有对网络方面感兴趣,php就比较蛋疼了,所以就抽了些时间看python 之前学python基础因为工作原因,断断续续的看了个基础,差不多是可以写代码了 最近在看<pyt ...
- 2.5 进程控制之wait函数
一.绪论 一个进程在终止时会关闭所有文件描述符,释放在用户空间分配的内存,但它的PCB还保留着,内核在其中保存了一些信息:如果 是正常终止则保存着退出状态,如果是异常终止则保存着导致该进程终止的信号是 ...
- 11 非阻塞套接字与IO多路复用(进阶)
1.非阻塞套接字 第一部分 基本IO模型 1.普通套接字实现的服务端的缺陷 一次只能服务一个客户端! 2.普通套接字实现的服务端的瓶颈!!! accept阻塞! 在没有新的套接字来之前,不能处理已经建 ...
- LeetCode 二叉树的层次遍历 C++
给定一个二叉树,返回其按层次遍历的节点值. (即逐层地,从左到右访问所有节点). 例如:给定二叉树: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回其层 ...
- vux用法
其实官网写的很详细了 但是好多时候没有仔细看的耐心 下面基本也是vux官网步骤: 很多人需要$t未定义问题 其实按着官网来就能解决这个报错: 如果你遇到 $t 报错问题,请不要开 issue,升级 v ...
- Web框架本质及浅谈HTTP协议
Web框架本质 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端. 这样我们就可以自己实现Web框架了. 半成品自定义web框架 impor ...
- Python 常见的字符串操作
1.strip.lstrip和rstrip 描述: 用于移除字符串左右两边.左边.右边指定的字符(默认为空白符,例如:/n, /r, /t, ' ')或字符序列. 语法: str.strip([cha ...
- Python第三方库之openpyxl(3)
Python第三方库之openpyxl(3) 区域图 区域图类似于折线图,绘图线下面的区域会被填充,通过将分组设置为“standard”.“stacked”或“percentStacked”,可以获得 ...
- react实现页面切换动画效果
一.前情概要 注:(我使用的路由是react-router4) 如下图所示,我们需要在页面切换时有一个过渡效果,这样就不会使页面切换显得生硬,用户体验大大提升: but the 问题是 ...
- Python目录链接
第1章 就这么愉快的开始吧 课时1:我和python的第一次亲密接触 一.Python3的下载与安装 二.从IDIE启动Python 三.尝试点新的东西 四.为什么会这样? 五.课时01课后习题及答案 ...