6.DLL中.def文件的使用

1.DLL导出函数的声明3种方式

1)在函数声明中添加_declspec(dllexport)

2)采用模块定义文件(.def)声明,.def文件为链接器提供了有关被链接程序的导出、属性及其他方面的信息

3)LINK命令中的/EXPORT规范

2.什么是模块定义文件

模块定义文件(.def)为链接器提供有关链接程序的导出、属性及其他方面的信息。生成DLL时,.def文件最有用。由于存在可代替模块定义语句的链接器选项,通常不需要.def文件

3..def文件的规则

1)LIBRARY语句:LIBRARY “库的名称”

2)注释:以分号(:)开头,且注释不能与语句共享一行

3)EXPORTS语句:后列出要导出函数的名称。可以在.def文件中的导出函数名后加@n,表示要导出函数的序号,.def文件可以包含一个或多个EXPORTS语句

4)entryname 【=内部名称】【@ordinal】【NONAME】【PRIVATE】【DATA】

NONAME关键字:允许只按序号输出,并减小结果DLL中导出表的大小

PRIVATE关键字:禁止将entryname放到又LINK生成的导入库中

DATA关键字:指定导出的是数据,而不是代码。

注意:语句、属性关键字和用户指定的标识符区分大小写

4..def文件实例

;注释导出DLL函数
LIBRARY  DLLTest

EXPORTS

SS1=SquareSum   @20

SS2=SumSquare   @24

Max=Max     @26   NONAME

Min=Min     @28   PRIVATE

等号前面是函数名称的别名,也是导出函数的名称;等号前后的名称可以一样

5.利用.def文件生成DLL库文件

DynamicLib32.cpp中:

#include "stdafx.h"

int SquareSum(int a, int b)
{
	return (a*a + b * b);
}

int SumSquare(int a, int b)
{
	return ((a + b)*(a + b));
}

int Max(int a, int b)
{
	return a > b ? a : b;
}

int Min(int a, int b)
{
	return a < b ? a : b;
}

利用.def文件导出函数后,就不必在函数定义前面加上_declspec(dllexport)了

在Source.def文件中:

LIBRARY

EXPORTS

SS1=SquareSum   @20

SS2=SumSquare   @24

Max=Max     @26   NONAME

Min=Min     @28   PRIVATE

生成的.dll文件在Dependency中打开:

 

6.测试.dll文件

main.cpp中:


#include <iostream>
#include <windows.h>
using namespace std;
//#include "func.h"
不需要.h头文件和.lib文件
//#pragma comment(lib,"DynamicLib32.lib")

int main()
{
	int a = 36;
	int b = 32;

	//加载DLL文件
	HMODULE h = LoadLibrary("DynamicLib32.dll");
	//定义一个函数指针类型
	typedef int(*PFUNC)(int, int);
	//通过函数名称来获取函数地址
	PFUNC pSquareSum = (PFUNC)GetProcAddress(h, "SS1");
	PFUNC pSumSquare = (PFUNC)GetProcAddress(h, "SS2");
	//PFUNC pMax = (PFUNC)GetProcAddress(h, "Max");     //错误,DLL没有改函数名称
	PFUNC pMin = (PFUNC)GetProcAddress(h, "Min");       //定义PRIVATE,外部项目还是可以运行
	//通过函数序号来获取函数地址
	PFUNC pMax = (PFUNC)GetProcAddress(h, (char*)26);   //只能通过序号来访问函数地址
	//PFUNC pSumSquare = (PFUNC)GetProcAddress(h, (char*)2);
	//调用函数
	cout << pSquareSum(a, b) << endl;
	cout << pSumSquare(a, b) << endl;
	cout << pMax(a, b) << endl;
	cout << pMin(a, b) << endl;
	//释放DLL文件
	FreeLibrary(h);

	system("pause");
	return 0;
}

执行结果:

1)如果在.def文件中定义函数属性为NONAME,则外部项目不能通过使用该函数的名称来调用该函数,只能通过函数序号来调用

2)目前还没发现PRIVATE的属性特点,在Dependency中跟其他函数一样,在外部项目中也能正常调用

 

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MSVC vs. MinGW 之 (lib,dll,def,obj,exe) vs (a,dll,def,o,exe) 玩转攻略手记 一份粗糙的研究记录,有待补完和整理。 MinGW: c -> o gcc -c a.c c -> exe gcc a.c libs.o -o a.exe (从主程序a.c,附加libs,生成a.exe) o -> exe gcc a.o b.o ... -o main.exe c -> dll,def,a gcc a.c -shared -o a.dll -Wl,--output-def,a.def,--out-implib,liba.a a -> dll a2dll liba.a dll -> a: dlltool --dllname a.dll --def a.def --output-lib liba.a (需要def文件) a -> def: dumpbin /exports lib.a > lib.def (在windows上调用,def需要修改) dll -> def : pexports a.dll -o > a.def (这里的-o是指给函数标序号) lib -> def : reimp -d a.lib lib -> a: (for __cdecl functions in most case) reimp a.lib; (for __stdcall functions) MSVC: c -> lib cl /LD a.c (注意已经定义了export列表) c -> dll cl /LD a.c c -> obj cl /c a.c c -> exe cl a.c /out:a.exe dll ->lib lib /machine:ix86 /def:a.def /out:a.lib (需要def文件) obj ->lib lib a.obj b.obj... /out:mylib.lib dll ->def DUMPBIN a.dll /EXPORTS /OUT:a.def (生成的def需要做修正) lib ->def reimp -d a.lib (这个要在MSYS+MinGW下用) 关于这些工具的适用范围可以很容易的理解和记忆。 dll和exe都是PE文件,所以可以使用pexports. lib和a是静态库文件,都是归档类型,不是PE格式。所以不能使用pexports. dll可以使用dlltool. lib可以使用lib, 和reimp(lib->a工具) 所有的bin文件,包括dll,exe,lib,a都可以使用dumpbin. 参考: http://hi.baidu.com/kaien_space/blog/item/5e77fafa2ba9ff16a8d3110a.html Mingw官网文档: http://www.mingw.org/wiki/MSVC_and_MinGW_DLLs http://oldwiki.mingw.org/index.php/CreateImportLibraries http://www.mingw.org/wiki/FAQ http://hi.baidu.com/opaquefog/blog/item/9b21b6deb324e25dccbf1ab7.html http://qzone.qq.com/blog/8330936-1238659272 http://hi.baidu.com/jzinfo/blog/item/b0aa1d308de99f9da8018e00.html 本篇测试用代码: 1. main.cpp #include #include #include "mylib.h" using namespace std; int main() { char str[]="Hello world!"; printhello(str); return 0; } 2. mylib.cpp #include #include #include "mylib.h" using namespace std; void EXPORT printhello(char *str) { cout << str << endl; } 3. mylib.h #define EXPORT __declspec(

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深山里的小白羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值