使用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应用:异常处理
Python的错误异常在大部分IDE编辑器中则可以直接显示出来,便于开发人员的调试及修改工作,对初学者也比较友好. Python中包含错误和异常两种情况,错误主要是常见的语法错误SyntaxError ...
- vue 项目如何使用微信分享接口
首先做微信网页都要接入微信sdk: 安装sdk npm install weixin-js-sdk --save 具体可以查看微信公众平台技术文档:https://mp.weixin.qq.com/w ...
- java练习题——类与对象
一.请依据代码的输出结果,自行总结Java字段初始化的规律 public static void main(String[] args) { InitializeBlockClass obj=new ...
- Delphi中客户端获取数据库更新信息(更新条数)
1.SQL语句 from tb where xxx='XXX') //不存在,则插入数据 begin insert into tb(xxx) values('XXX') //这里自己定义,插入或更新都 ...
- 【python3.X】Scrapy学习途径参考
如何爬取属性在不同页面的itemhttp://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/request-response.html#topics-requ ...
- html简单的分享功能
超级简单的分享. 包括:QQ.QQ空间.新浪微博.腾讯微博,微信(只是一个二维码): 1.首先是html代码: (前端我并不太会,一直用的都是bootstrap) <div class=&quo ...
- Linux 文件属性及修改权限
输入 ll 或 ls -l 命令显示当前目录中文件的属性及文件所属的用户和组 root@user:/home/www# ll test total 880 drwxr-xr-x 2 root root ...
- 第三十篇 面向对象的三大特性之继承 supre()
继承 一 .什么是继承? 类的继承跟现实生活中的父.子.孙子.重孙子的继承关系一样,父类又称基类. Python中类的继承分为:单继承 和 多继承. # 定义父类 class ParentClass ...
- Python网络编程(进程通信、信号、线程锁、多线程)
什么是进程通讯的信号? 用过Windows的我们都知道,当我们无法正常结束一个程序时, 可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢? 同样的功能在Linux上是通过生成信号和捕获信号来实 ...
- 51单片机数码管字符H自右向左移动
#include <reg51.h> #define uint unsigned int #define uchar unsigned char sfr P0M0 = 0x94; sfr ...