孙鑫:第十九讲 动态链接库
来源:互联网 发布:linux ar命令 编辑:程序博客网 时间:2024/05/17 06:00
静态库和动态库
静态库:函数和数据被编译进一个二进制文件(通常扩展名为.LIB)。在使用静态库的情况下,在编译链接可执行文件时,链接器从库中复制这些函数和数据并把它们和应用程序的其他模块组合起来创建最终的可执行文件(.EXE文件);
在使用动态库的时候,往往提供两个文件:一个因入库和一个DLL。因入库包含被DLL导出的函数和变量的符号名,DLL包含实际的函数和数据。在编译链接可执行文件时,只需要链接引入库,DLL中的函数代码和数据并不复制到可执行文件中,在运行时候,再去加载DLL,访问DLL中导出的函数。
使用动态链接库的好处
可以采用多种编程语言来编写。
增强产品的功能。
提供二次开发的平台。
简化项目管理
可以节省磁盘空间和内存。
有助于资源的共享。
有助于实现应用程序的本地化
建立DLL文件代码如下:
_declspec(dllexport) int Add(int x,int y)
{
}
_declspec(dllexport) int Subtract(int x,int y)
{
}
//必须带_declspec(dllexport)文件,以生成*.lib文件
如果要查找*dll中包含信息,可在命令行下进入Debug所在目录,输入以下命令
dumpbin -exports dll.dll
有些时候由于某种安装原因,dumpbin被认为是无效命令,接下来在
C:\Program Files\Microsoft Visual Studio\VC98\Bin\下找到VCVARS32.bat并在命令行运行,之后就能执行dumpbin命令了。
新建MFC程序,新建两个按钮,代码如下:
void CDllTestDlg::OnBtnAdd()
{
}
void CDllTestDlg::OnBtnSubtract()
{
}
为使编译器认识Add,Subtract,必须在之前使用两个声明:
extern int Add(int x,int y);
extern int Subtract(int x,int y);
可以使用标示符表示这两个函数是从动态链接库的.lib文件引用的,以生成效率更高的代码
_declspec(dllimport) int Add(int x,int y);
_declspec(dllimport) int Subtract(int x,int y);
这两段代码我们也可以在DLL中新建一个头文件放进去,并在MFC程序中添加头文件
如#include "..\Dll\Dll.h"
从原先Dll文件下Debug目录中复制*.lib到MFC程序文件夹下,并添加库函数
在project--->setting--->link--->Object/Library Modules写下所复制的文件名
如果要查看DllTest.exe文件信息,使用命令行dumpbin -imports dlltest.exe
修改动态链接库Dll.h
#ifdef DLL_API
#else
#define DLL_API _declspec(dllimport)
#endif
DLL_API int Add(int x,int y);
DLL_API int Subtract(int x,int y);
修改Dll.cpp文件
#define DLL_API _declspec(dllexport)
#include "Dll.h"
int Add(int x,int y)
{
}
int Subtract(int x,int y)
{
}
这样做是为了方便外部程序调用同时方便内部程序使用,因为动态链接库中只有导出的函数才可以被使用,没有导出的函数在外部是看不到的,是不能被访问的
接下来导出整个类,代码:
class DLL_API point
{
public:
};仍然受制于访问权限
实现:
void Point::output(int x,int y)
{
}
接下来在MFC程序新建一个按钮,调用动态链接库函数,代码如下:
因为C++导出或导入动态链接库会发生名字的改编,如果不想发生名字改编,我们可以使用如下代码:
#define DLL_API
这样编译器就不会进行名字改编,一个用C语言编写的客户端程序就可以调用这个用C++编写的动态链接库。其缺点是,不能导入类中的函数
如果函数使用标准调用约定_stdcall,即使使用了extern "c",此函数仍会发生改编
接下来新建一个动态链接库文件,文件名为Dll2,cpp文件代码为:
int Add(int x,int y)
{
}
int Subtract(int x,int y)
{
}
为了最终解决问题,我们可以新建一个模块文件Dll.def,以使得其他语言编制的程序也能使用我们的动态链接库。
添加代码
LIBRARY Dll2
EXPORTS
Subtract
EXPORTS 语句引入了一个由一个或多个 definitions(导出的函数或数据)组成的节。每个定义必须在单独一行上。EXPORTS 关键字可以在第一个定义所在的同一行上或在前一行上。.def 文件可以包含一个或多个 EXPORTS 语句。
导出 definitions 的语法为:
entryname[=internalname] [@ordinal [NONAME]] [PRIVATE] [DATA]
entryname 是要导出的函数名或变量名。这是必选项。如果导出的名称与 DLL 中的名称不同,则通过 internalname 指定 DLL 中导出的名称。例如,如果 DLL 导出函数 func1(),要将它用作 func2(),则应指定:
EXPORTS
func2=func1
@ordinal 允许指定是序号而不是函数名将进入 DLL 的导出表。这有助于最小化 DLL 的大小。.LIB 文件将包含序号与函数之间的映射,这使您得以像通常在使用 DLL 的项目中那样使用函数名。
可选的 NONAME 关键字允许只按序号导出,并减小结果 DLL 中导出表的大小。但是,如果要在 DLL 上使用 GetProcAddress,则必须知道序号,因为名称将无效。
可选的 PRIVATE 关键字禁止将 entryname 放到由 LINK 生成的导入库中。它对同样是由 LINK 生成的图像中的导出无效。
可选的 DATA 关键字指定导出的是数据,而不是代码。例如,可以导出数据变量,如下所示:
EXPORTS
i DATA
接下来在MFC文件中改写按钮void CDllTestDlg::OnBtnAdd() 代码:
//如果在DLL的函数中调用_stdcall,相应的应该把代码改为
//typedef int (_stdcall *ADDPROC)(int a,int b);
因为调用LoadLibrary时动态加载动态链接库,所以不需要头文件和.lib文件
如果我们在动态链接库中使用标准调用约定_stdcall,而在可执行程序中使用动态加载DLL,会发生名字重编,如果知道DLL中函数的序号,这时可以使用宏MAKEINTRESOURCE把序号转变成名字,如:
ADDPROC Add=(ADDPROC)GetProcAddress(hInst,MAKEINTRESOURCE(1));
DllMain
The DllMain function is an optional entry point into a dynamic-link library (DLL). If the function is used, it is called by the system when processes and threads are initialized and terminated, or upon calls to the LoadLibrary and FreeLibrary functions.
DllMain is a placeholder for the library-defined function name. You must specify the actual name you use when you build your DLL. For more information, see the documentation included with your development tools.
BOOL WINAPI DllMain(
);
当我们的动态链接库不再使用时可以调用FreeLibrary使动态链接库使用计数减1,当使用计数为零时,系统会收回模块资源
FreeLibrary
The FreeLibrary function decrements the reference count of the loaded dynamic-link library (DLL). When the reference count reaches zero, the module is unmapped from the address space of the calling process and the handle is no longer valid.
BOOL FreeLibrary(
);
- 孙鑫:第十九讲 动态链接库
- 孙鑫VC学习笔记:第十九讲 动态链接库
- 孙鑫VC学习笔记:第十九讲 动态链接库
- MFC(动态链接库编程,孙鑫C++第十九讲笔记整理)
- MFC- 动态链接库编程(孙鑫-第十九讲笔记整理)
- 孙鑫 第十九课 动态链接库DLL
- 孙鑫MFC第十九章 动态链接库编程
- 《VC++深入详解》学习笔记 第十九章 动态链接库
- 孙鑫MFC第十九讲DLL
- 第十九讲
- linux动态链接库---一篇讲尽
- 孙鑫《vc++深入详解》第十九章动态链接库
- 第十九讲:其他类
- 第十九讲-多态续
- 读书笔记(第十九讲)polymorphism
- 韩顺平网页第十九讲
- Linux运维第十九讲
- 孙鑫 动态链接库DLL
- 孙鑫: 第十七讲 进程间通信四种方式
- .net中输出变量到aspx页面
- USACO Section 3.2 Factorials - 高精度模拟~
- 孙鑫:第十八讲 ActiveX 控件
- C格式读取文件
- 孙鑫:第十九讲 动态链接库
- wordpress修改固定链接后打不开文章链接的处理
- se16n and &sap_edit
- Linux内核学习之系统调用
- java-mysql-apm(apache+php+mysql)中文乱码解决方法
- 孙鑫:第二十讲 Hook过程函数与数据库基础知识
- html简单 字母数字 加密 解密 实例
- callee和caller
- android_Lame转换音频格式