VC++程序设计与应用--动态链接库

Posted Abro.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VC++程序设计与应用--动态链接库相关的知识,希望对你有一定的参考价值。

目录

前言

一、动态链接库

1.1 概述

1.1.1 动态链接库的概念

1.1.2 动态链接库和静态链接库的区别

1.1.3 使用动态链接库的优点

1.1.4 DLL文件的存放位置

1.2 创建MFC DLL

1.2.1 使用DEF文件

1.2.2 使用关键字_declspec(dllexport)

1.3 使用MFC DLL

1.3.1 使用隐式链接

1.3.2 使用显式链接

1.4 MFC拓展DLL

1.4.1 创建MFC扩展 DLL

总结


前言

本篇文章介绍动态链接库


一、动态链接库

1.1 概述

在多任务环境中,为了提高系统资源的利用率和系统的整体性能,应该使每一个应用程序尽量少占用系统内存等资源。

    动态链接库便是这一设想的体现,允许多个应用程序同时共享动态链接库在内存中的同一份拷贝。

1.1.1 动态链接库的概念

动态链接库(DLL):一种用来为其它可执行文件(包括EXE文件和其它DLL)提供共享的函数库。   

    DLL中一般定义有两种类型的函数:导出函数和内部函数。导出函数是可以被外部程序调用的函数,内部函数只能在DLL内部使用。

1.1.2 动态链接库和静态链接库的区别

动态链接库和静态链接库的主要区别是与应用程序的链接方式不同,前者进行的是动态链接,后者进行的是静态链接。

1.1.3 使用动态链接库的优点

(1) 实现多个应用程序共享数据和代码的方式。

(2) 提高应用程序的执行效率和运行速度。

(3) 方便应用程序的升级和售后支持。

(4)把应用程序所使用的资源,如图标、位图、字符串和对话框等,独立出来做成DLL,为多个应用程序所共享。

(5) 动态链接库便于建立多语言的应用程序。

1.1.4 DLL文件的存放位置

程序所需的DLL文件必须位于下面4个目录之一中:

(1) 当前目录

(2) Windows的系统的目录,如Windows\\system

(3) Windows所在的目录,如WINNT

(4) 环境变量PATH中所指定的目录

1.1.5 动态链接库的分类

Visual C++ 6.0支持多种DLL,包括:

  • MFC DLL

        一般来说,非MFC DLL的内部不使用MFC,非MFC DLL的导出函数都使用标准的C接口,因此无论应用程序是否使用了MFC,都可以调用非MFC DLL

  • MFC扩展DLL

    MFC扩展DLL一般用来提供派生于MFC的可重用的类,以扩展已有的MFC类库的功能。MFC扩展DLL使用MFC的动态链接版本。只有使用MFC生成的可执行程序(无论是EXE还是DLL)才能访问MFC扩展DLL

1.2 创建MFC DLL

利用MFC AppWizard[dll]向导可以创建MFC DLLDLL文件与可执行文件非常相似,不同点在于DLL包含有导出表。导出表包含DLL中每个导出函数的名字,这些函数是进入DLL的入口点。只有导出表中的函数可以被外部程序调用。

    从MFC DLL中导出函数常用以下两种方法:使用模块定义文件(.def)和使用关键字_declspec(dllexport)

1.2.1 使用DEF文件

DEF文件是一个包含EXE文件或DLL文件声明的文本文件。每个DEF文件至少必须包含LIBRARY语句和EXPORTS 语句,其他语句可以省略。

DEF文件常用的模块语句如下:

  1. 第一个语句必须是LIBRARY语句,这个语句指出DLL的名字,链接器将这个名字放到DLL导入库中,DLL导入库包含了指向外部DLL的函数索引指针。
  2. EXPORTS 语句列出被导出函数的名字, 以及导出函数的数值(由@号与数字构成)。序数值可以省略,编译器会为每个导出函数指定一个,但这样指定的值不如自己指定的明确。
  3. 使用DESCRIPTION语句描述DLL的用途,这个语句可以省略。
  4. 使用开头的注释语句。

1.2.2 使用关键字_declspec(dllexport)

MFC DLL中导出函数的另一种方法是在定义函数时使用关键字_declspec(dllexport)。这种情况下,不需要DEF文件。导出函数的形式为:

declspec(dllexport) <返回类型> <导出函数名>(<函数参数>)

1.2.3 两种导出函数方法的比较

  • 如果需要使用导出顺序值,那么应该使用DEF文件来导出函数。
  • 使用DEF文件来导出函数,可以创建具有NONAME属性的DLL
  • 使用declspec(dllexport)关键字导出函数不需要编写DEF文件,因此,如果编写的DLL只供自己使用,使用__declspec(dllexport)较为简单。

1.3 使用MFC DLL

应用程序与DLL链接后,DLL才能通过应用程序调用运行。应用程序与DLL链接的方式主要有如下两种:隐式链接和显式链接。

    隐式链接又称为静态加载,指的是使用DLL的应用程序先链接到编译DLL时生成的导入库LIB文件,执行应用程序的同时操作系统自动加载所需的DLL在应用程序退出之前,DLL一直存在于该程序运行进程的地址空间中。

    显式链接又称为动态加载,使用显式链接DLL的应用程序必须在代码中动态地加载所使用的DLL,并使用指针调用DLL中的导出函数,在使用完毕后,应用程序必须卸载所使用的DLL

1.3.1 使用隐式链接

使用隐式链接除了需要相应的DLL文件外,还必须具备以下2个文件:

  • 包含导出函数以及类声明的头文件
  • DLL的导入库LIB文件

 编译时将DLL的LIB文件加入应用程序中,主要有如下3种方法。

  1. 在主菜单project中,选择菜单项【Add To Project| Files】菜单项,在弹出的Insert Files Into Project对话框中选择所需的LIB文件。
  2. 在程序的StdAfx.h头文件中加入下列语句:#pragma comment (lib,"指定的LIB文件名")
  3. 在主菜单project中,选择【Settings】菜单项,弹出Project Settings对话框,如下图所示。选择Link选项卡,在Object/library modules文本框中输入指定的LIB文件名,多个库文件之间用空格分开。

1.3.2 使用显式链接

使用显式链接时,需要知道导出函数返回值的类型和所传递的参数个数、类型和顺序等。应用程序在调用DLL中的导出函数前,必须首先调用LoadLibrary()函数加载DLL并得到一个模块句柄,然后使用得到的模块句柄调用GetProcAddress()函数获取导出函数的指针,并使用该指针调用DLL中的导出函数。DLL使用完毕后,调用FreeLibrary()函数释放加载的DLL

    若DLLMFC扩展DLL,则应用程序应该分别使用AfxLoadLibrary()AfxFreeLibrary()函数来加载和释放DLL

1.4 MFC拓展DLL

MFC扩展DLL的含义在于它是MFC的扩展,其主要功能是实现从现有MFC类库中派生出可重用的类。

1.4.1 创建MFC扩展 DLL

    对于MFC扩展DLL,系统会自动在项目中添加如下表所示的宏,这些宏为DLL和应用程序的编写提供了方便。   例如MFC扩展DLL除了可使用关键字_declspec(dllexport) 导出类外,还可以使用宏AFX_EXT_CLASS来导出类,而链接到MFC扩展DLL的可执行文件同样使用这个宏来导入类。


总结

机会就像坐公交车,有人上车早,有人上车晚,有人直达车,有人要转车。只要你有决心去目的地,一定可以找到自己的路线!

以上是关于VC++程序设计与应用--动态链接库的主要内容,如果未能解决你的问题,请参考以下文章

opencv静态链接库有啥用

常用动态链接库的DLL都有哪些?

VC6.0创建DLL动态链接库四大要素

电脑应用程序错误,怎么办?

求欧姆龙Fins协议动态链接库或者VC与欧姆龙Fins通讯例子。

VC/MFC动态库Debug版本下正常,Release版本下错误