DLL学习笔记(VS2005)
建立DLL项目
项目的相关配置:
l DLL输出
项目属性-->连接器-->常规-->输出文件:更改生成的DLL文件名。
l 模块定义文件(后面详述)
项目属性-->连接器-->常规-->输入-->模块定义文件:更改def文件名。
导出定义的方法
有三种导出定义的方法,按照建议的使用顺序依次为:
1. 源代码中的 __declspec(dllexport)
2. .def 文件中的 EXPORTS 语句
3. LINK 命令中的 /EXPORT 规范
所有这三种方法可以用在同一个程序中。
编写导出函数
stdafx.h 或 头文件里
#define DLL_EXPORT __declspec(dllexport)
#define DLL_IMPORT __declspec(dllimport)
声明:
extern "C" {
DLL_EXPORT int Add(int x, int y);
DLL_EXPORT void Function();
}
使用DLL——动态(函数指针)
(1)声明 函数指针
typedef int(*lpAddFun)(int, int);
typedef void(*lpFunction)();
(2)获取DLL
HINSTANCE hDll; // 实例句柄,这里是DLL的句柄
hDll = LoadLibraryW(_T("..//Debug//MyLib1.dll"));
if (hDll == NULL) {
FreeLibrary(hDll);
}
(3)获取DLL中的函数
lpAddFun _AddFun; // lpAddFun 函数指针
lpFunction _Function; // lpFunction 函数指针
_AddFun = (lpAddFun)GetProcAddress(hDll, "Add");
_Function = (lpFunction)GetProcAddress(hDll, "Function");
(4)使用DLL中的函数
_Function();
std::cout << _AddFun(10, 25) << std::endl;
(5)释放DLL
FreeLibrary(hDll);
·
使用DLL——静态
#pragma comment(lib, "..//Debug//MyLib1.lib")
extern "C" {
DLL_IMPORT int Add(int x,int y);
DLL_IMPORT int Function();
}
int main(int argc, char* argv[]) {
Function();
std::cout << Add(10, 25) << std::endl;
return 1;
}
模块定义文件 (*.def)
l 通常也可以不编写此文件,因为存在可代替模块定义语句使用的链接器选项。
l 也可以将 __declspec(dllexport) 用作指定导出函数的手段。
(一)模块定义语句规则:
下列语法规则适用于 .def 文件中的所有语句。其他适用于特定语句的规则与各语句一起加以说明。
· 语句、属性关键字和用户指定的标识符区分大小写。
· 包含空格或分号 (;) 的长文件名必须用引号 (") 引起。
· 使用一个或多个空格、制表符或换行符,将语句关键字同其参数分开和将各语句分开。指定参数的冒号 (:) 或等号 (=) 两旁有零个或多个空格、制表符或换行符。
· 如果使用 NAME 或 LIBRARY 语句,则这些语句必须位于所有其他语句之前。
· 在 .def 文件中,SECTIONS 和 EXPORTS 语句可以出现多次。每个语句都可以采用多个规范,各规范间必须用一个或多个空格、制表符或换行符分开。语句关键字必须在第一个规范的前面出现一次,并且可以在每个附加规范的前面重复。
· 许多语句都具有等效的 LINK 命令行选项。有关其他详细信息,请参见相应的 LINK 选项说明。
· .def 文件中的注释由每个注释行开始处的分号 (;) 指定。注释不能与语句共享一行,但可以在多行语句的规范间出现。((SECTIONS 和 EXPORTS 为多行语句。)
· 以十进制或十六进制为基础指定数值参数。
· 如果字符串参数与保留字匹配,则必须用双引号 (") 将字符串参数引起。