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中跟其他函数一样,在外部项目中也能正常调用
上一篇: resttemplate 发送get请求
下一篇: VC生成DLL并且调用DLL文件