动态链接库

动态链接库

静态库:一个二进制文件(通常拓展名为.LIB)。在程序编译时,链接器将库中的函数和数据复制创建最终的可执行文件(.EXE文件)。因此发布时不需要使用静态链接库。

动态库:包含一个引入库(.lib)文件和一个DLL(.dll)文件。与静态库不同,引入库包含DLL导出的函数和变量符号,而.dll文件包含DLL实际的函数和数据。是程序编译时,链接器只复制引入库的内容生成可执行文件。直到可执行程序运行时,才回去加载所需的DLL,将该DLL映射到进程的地址空间中,然后访问DLL中导出的函数。因此,发布时需要同时发布动态链接库。(DLL可以包含对话框模板、字符串、图标和位图等资源)


动态链接库优势

  • 实现多种语言编写
  • 增强产品功能(插件、DLL规范拓展等)
  • 方便二次开发
  • 简化项目管理
  • 节省磁盘空间
  • 有助于资源共享
  • 有助于实现程序语言国际化

动态链接库的创建

1. Win32 DLL创建

1)VS创建一个Win32 DLL空项目;

2)添加CPP文件,如需h文件也可以添加。编写正常C++/C代码

3) 对于全局函数而言,在需要导出函数前添加_declspec(dllexport)。对于类而言,若想导出类的所有成员函数,在类名前添加_declspec(dllexport);若想导出部分成员函数,则在相应函数前添加_declspec(dllexport)。

4)编译执行,获得.lib文件和.dll文件

2. MFC DLL创建

与Win32 DLL过程类似,只是增加了MFC函数的支持。包含三种,a)常规静态MFC链接 b)常规共享MFC链接 c)拓展共享MFC链接。 后两者的区别,前者不能导出MFC类,后者可以。

3. “名字改编”问题的解决

说明:编译器在导出DLL时,会改编函数的名称,不同编译器、不同语言的改变规则不一样。因此在发布和客户端两者的规则不一样时,会导致客户端无法使用DLL里面的函数。

法1: 在_declspec(dllexport)和_declspec(dllimport)前均加上extern “C”,注意C一定要大写。这种方法的缺点是不能用于导出一个类的成员函数,只能用于全局函数。此外,若函数调用约定改变,这种方式也会失效,如在_declspec(dllexport)和_declspec(dllimport)后,函数名前加入_stdcall关键字。

法2: 不使用_declspec(dllexport)方式导出,在函数前不加任何修饰符,在项目中添加一个.def后缀名的文件,并在里面添加如下代码:

LIBRARY DLL文件名     //可有可无

EXPORTS
函数名1
函数名2
新函数名=函数名3

4.隐式/显示加载DLL

隐式加载

  • 将.lib和.dll文件复制到工程目录,其中dll可以放在DEBUG目录下。(注意:编译时dll搜索顺序:项目执行目录,当前项目目录,系统目录,path环境变量目录)
  • 使用extern声明dll的函数。如下,

    extern int add(int a, int b)
    
  • 不用extern,利用_declspec(dllimport)声明外部函数【推荐这种】。如下,

    _declspec(dllimport) int add(int a, int b)
    

显示加载

HINSTANCE hInst;
hInst=LoadLibrary("XXX.dll");//加载DLL
typedef int (*XXX)(int a, int b);//定义函数指针,与DLL里函数形式要一致
XXX x=(XXX)GetProcAddress(hInst, "dll里函数名");
if(!x)
{
  MessageBox("获取函数地址失败");
  return;
}
//接下来就可以调用x函数指针了
//需要注意的是,在不使用DLL后,可以释放
FreeLibrary(hInst);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值