模块定义文件.def
一作用
DLL中导出函数的声明有两种方式:一种为在函数声明中加上__declspec(dllexport),这里不再举例说明;另外一种方式是采用模块定义(.def) 文件声明,.def文件为链接器提供了有关被链接程序的导出、属性及其他方面的信息。
在链接器阶段可以使用 /DEF(指定模块定义文件)链接器选项调用 .def 文件。如果生成的 .exe 文件没有导出,使用 .def 文件将使输出文件较大并降低加载速度。
二原因
在VC++中,生成DLL可以不使用.def文件。只需要在VC++的函数定义前要加__declspec(dllexport)修饰就可以了。但是使用__declspec(dllexport)和使用.def文件是有区别的。如果DLL是提供给VC++用户使用的,你只需要把编译DLL时产生的.lib提供给用户,它可以很轻松地调用你的DLL。但是如果你的DLL是供其他程序如VB、delphi,以及.NET用户使用的,那么会产生一个小麻烦。因为VC++对于__declspec(dllexport)声明的函数会进行名称转换,如下面的函数:
__declspec(dllexport) int __stdcallIsWinNT()
会转换为IsWinNT@0,这样你在VB中必须这样声明:
Declare Function IsWinNT Lib "my.dll" Alias "IsWinNT@0" () As Long
@的后面的数由于参数类型不同而可能不同。这显然不太方便。所以如果要想避免这种转换,就要使用.def文件方式。
EXPORTS后面的数可以不给,系统会自动分配一个数。对于VB、PB、Delphi用户,通常使用按名称进行调用的方式,这个数关系不大,但是对于使用.lib链接的VC程序来说,不是按名称进行调用,而是按照这个数进行调用的,所以最好给出。
三 使用
例1:我们用VC6.0制作一个dll(动态链接库),不使用.def文件,在头文件中这样写
#ifndef LIB_H
#define LIB_H extern "C" int _declspec(dllexport)add(int x,int y);
#endif
如果是.def文件,可以这样 LIBRARY "xxx_dll" EXPORTS add PRIVAT
例2:首先创建 一个DLL程序,.cpp中
int __stdcall Sub(int numa, int numb)
{
return (numa - numb);
}
然后创建一个.def的文件,在里面加上
;DllTestDef.lib : 导出DLL函数
;作者:----
LIBRARY DllTestDef
EXPORTS
Add @ 1
Sub @ 2
最后创建一个测试程序:.cpp文件如下:
#include <iostream>
#include <windows.h>
using namespace std;
typedef int (__stdcall *FUN)(int, int);
HINSTANCE hInstance;
FUN fun;
int main()
{
hInstance =
LoadLibrary("DLLTestDef.dll");
if(!hInstance)
cout <<
"Not Find this Dll" << endl;
fun = (FUN)GetProcAddress(hInstance,
MAKEINTRESOURCE(1));
if (!fun)
{
cout
<< "not find this fun" << endl;
}
cout << fun(1, 2) <<
endl;
FreeLibrary(hInstance);
return 0;
}
说明:
.def文件的规则为:
(1)LIBRARY语句说明.def文件相应的DLL;
(2)EXPORTS语句后列出要导出函数的名称。可以在.def文件中的导出函数名后加@n,表示要导出函数的序号为n(在进行函数调用时,这个序号将发挥其作用);
(3).def 文件中的注释由每个注释行开始处的分号 (;) 指定,且注释不能与语句共享一行。
模块定义文件.def的更多相关文章
- [转]VS2010中使用模块定义文件(.def)
都知道在写DLL的时候,使用模块定义文件(.def)可以防止DLL里的命名变更. vc6.0中只要在当前目录下添加.def文件,然后编译就Ok了 但在vs2010里这样做是不可以的,必须在项目--属性 ...
- 2016-03-15:关于VS中模块定义文件
1 def模块定义文件 在使用开源库libx265时,因x265项目的头文件x265中有如下的宏定义 #ifdef X265_API_IMPORTS #define X265_API __declsp ...
- 创建DLL动态链接库——模块定义法(def)
DLL模块定义法(Module-Definition File,即DEF):在VS家族IDE中,根据提示新增.def文件,如下: LIBRARY 关键字; mytestDll 库名; DLL_ADD ...
- 详解模块定义(.def)文件
一个完整的Windows应用程序(C++程序)通常由五种类型的文件组成:源程序文件,头文件,资源描述文件,项目文件,模块定义文件.本文主要讲解模块定义文件. 模块定义 (.def)文件为链接器提供有关 ...
- DLL用def定义文件来导出重载函数(转)
动态链接库DLL_Sample.dll DLL_Sample.h:#ifdef TEST_API# define TEST_API _declspec(dllexport)#else# define ...
- TypeScript 学习四 面向对象的特性,泛型,接口,模块,类型定义文件*.d.ts
1,面向对象的特性一:类,继承,见上一篇博客: 2,面向对象的特性二: 泛型(generic):参数化的类型,一般用来限制集合的内容:指定只能放某个类型的元素 如下图中的尖括号中的Person,就代表 ...
- Python模块定义和使用
Python中所谓的模块就是一个Python文件,一个abc.py的文件就是一个名字叫abc的模块,一个xyz.py的文件就是一个名字叫xyz的模块.模块由代码.函数或类组成.编程中使用模块不仅可以提 ...
- Python第二模块(文件和函数)
1. 集合操作 集合的特点:无序,不重复的数据组合 集合的作用: 去重,将列表变为集合,就会自动去重 关系测试,测试两组数据之间的交集.差集.并集关系 常用操作: #创建集合 s = {1,2, ...
- CMD规范(通用模块定义规范)(翻译)
最近在使用sea.js.大家知道sea.js遵循CMD规范.该规范的英文说明很简洁,我试着翻译了一下,旨在交流. Common Module Definition 通用模块定义规范 This spec ...
随机推荐
- SpringBoot多数据源配置事务
除了消费降级,这将会是娱乐继续下沉的一年. 36氪从多个信源处获悉,资讯阅读应用趣头条已经完成了腾讯领投的Pre-IPO轮融资,交易金额预计达上亿美元,本轮融资估值在13-15亿美金之间:完成此轮融资 ...
- 后渗透提权辅助工具BeRoot详解
0x00 工具介绍 前言 BeRoot是一个后期开发工具,用于检查常见的Windows的配置错误,以方便找到提高我们提权的方法.其二进制编译地址为: https://github.com/Alessa ...
- C内存对齐问题-bus error!总线错误!其实是 字符串字面量修改问题!
最近写个小程序,出现bus error! int main(void) { /** * char :1个字节 * char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也 ...
- 日志分割工具——cronolog
使用cronolog可以格式化日志文件的格式,比如按时间分割,易于管理和分析. 1.下载软件 http://cronolog.org/download/index.html 用法见 lighttpd配 ...
- 第13章 MySQL服务器的状态--高性能MySQL学习笔记
13.1 系统变量 -- 服务器配置变量 MySQL通过SHOW VARIABLES SQL命令显示许多系统变量. 13.2 状态变量--SHOW STATUS SHOW STATUS 命令会在一个 ...
- Introducing my blog
作为一名计算机专业的学生,在我的博客中我会记录以下几方面的内容: 1.在阅读各类专业书籍的过程中,遇到了一些自己通过很大努力才思考.解决出来的问题/知识/概念,我会通过我自己的讲解将这些问题较为全面. ...
- Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1)A B C 水 并查集 思路
A. Bear and Big Brother time limit per test 1 second memory limit per test 256 megabytes input stand ...
- Codeforces 25.E Test
E. Test time limit per test 2 seconds memory limit per test 256 megabytes input standard input outpu ...
- Git之git push不手动输入用户名和密码
每次git push时都要输入用户名和密码,感觉很啰嗦,总结了网上的解决办法,有的发现不可以(原因未知),记录一个对我自己可用的方式,我的是windows. 1:添加环境变量 2:在%HOME%目录下 ...
- 手脱PEncrypt 4.0
1.载入PEID PEncrypt 4.0 Gamma / 4.0 Phi -> junkcode [Overlay] 2.载入OD,没什么头绪,忽略所有异常,用最后一次异常法shift+F9运 ...