Lib和Dll的那点事

作者: NickYang 分类: 技术文章,程序开发 发布时间: 2012-11-01 09:40

搞程序开发的朋友应该对Lib和Dll很熟悉,对于这两个东西,可谓是几家欢喜几家忧,喜欢的人觉得它可以封装代码,避免别人剽窃,不喜欢的人觉得它很麻烦,干嘛不直接用源文件。而特别是新手对于Lib和Dll的关系和使用完全搞不清楚。

Lib称为静态链接库(static link library),是在编译的链接期间使用的,他里面其实就是源文件的函数实现。

Dll成为动态链接库(Dynamic link library),是在程序运行时动态调用的,runtime时使用,它里面包含了源文件的函数实现、DllMain入口函数和.def文件。

先说说Lib库吧,相对来说大家对它比dll熟悉一些。

Lib库

Lib库有两种,一种就是常见的普通Lib(static Lib),还有一种大家经常下载的开源代码编译后,会产生Lib和dll,其中Lib只是Dll的附带品,是DLL导出的函数列表文件而已,暂且称之为Dynamic Lib。

两者都是二进制文件,两者都是在链接是调用的,使用static lib的exe可直接运行,使用dynamic lib的exe需要对应的dll才能运行。下来我们来看如何产生并使用一个static lib文件。

这里假设我们的工具是VS2005(包含)以上的版本,其他的工具都是大同小异的,就不做介绍了。

1.建立win32控制台工程

2.在应用程序设置的步骤,选择”静态库 static Library”

3.完成即可 (这里只是针对最简单的Dll,Win32 Application的方式稍有不同)

这样一个静态Lib库的工程就建好了。代码如下:

编译会生成一个以工程名作为名称的Lib文件。

在你的项目工程属性中包含这个Lib文件的头文件目录和Lib文件目录。

头目录包含方法:项目属性(Alt + F7) -> 配置属性 -> C/C++ -> 常规 -> 附加包含目录,里面包含你的Lib库的头文件,你可以使用绝对路径,也可以使用VS中宏表示的相对路径,建议使用相对路径。

Lib文件包含方法:项目属性(Alt + F7) -> 配置属性 -> 链接器 -> 常规 -> 附加库目录,在这里面填写你Lib文件的路径。项目属性(Alt + F7) -> 配置属性 -> 链接器 -> 常规 -> 输入,在这里面填写你Lib文件的名称,例如: Function.lib

这样你在你的代码里就可以这样使用了:

这样就是一个完整生成并使用Lib库的例子。

当然了,你还可以使用#pragma comment(Lib, “LibPath”)的方法来调用Lib文件。

==============================================================

Dynamic Lib的调用方法与Static lib完全一致,唯一的区别就是使用Dynamic Lib编译出来的程序,运行时需要其对应的Dll文件。前面我们已经说过了。

DLL

下来我们好好谈谈Dll的问题,相对于Lib来说,Dll使用的频率应该是非常高的了,因为你的程序运行,系统运行等等都靠它,MS也是因为这个才导致操作系统封装的越来越好了。

Dll其实和Exe是几乎完全一样的,唯一的不一样就是Exe的入口函数式WinMain函数(console程序是main函数),而Dll是DllMain函数,其他完全是一样的。所以有人也戏称Dll是不能自己运行的Exe。

Dll创建的过程也比较简单,唯一麻烦的就是需要定义导出函数接口。

创建Dll工程过程很简单,建立win32控制台工程,在应用程序设置的步骤,选择”动态库 Dynamic Library”,完成即可。(这里只是针对最简单的Dll,Win32 Application的方式稍有不同)

定义导出函数接口有两种方式:

1.使用__declspec宏

这里假设我们的工程名叫Function,那么 编译后会生成一个Function.dll和一个Function.lib(Dynamic lib),Dynamic lib前面已经说过,此处不再赘述了。

Function.h头文件中的

我们只需要清楚其中函数的名称,返回值,参数就可以了。

extern “C”表示我们要按照C语言的方式编译该函数,防止在C++工程中编译出现函数名错误,因为C++中有函数重载,所以函数名编译后可能会出现Print@1的形式;而且这样也可以让C调用C++的动态链接库;__declspec(dllexport)表示下来的函数是dll的导出函数接口。

2.使用def文件,类似于声明导出接口的方式,不过却不需要声明了,因为它专门定义了一个def文件来说明

同样,类似于Static Lib的显式调用方法,dll也可以显式调用,前提是我们很清楚函数名、返回值、参数列表。

 

当然了,有显式自然还有隐式调用了,这个时候Function.dll的伴生产物Function.lib就可以派上用场了,其使用方法和静态lib完全相同。

DLL调用的两种方法各有利弊:采用寻找DLL中函数地址的方法,优点是只要函数形参没变化,那么修改了函数实现也没关系,不需要重新编译Exe,只需要将新的DLL文件拷贝过来即可,大型项目上使用比较灵活;缺点是比较麻烦,需要定义实例,函数指针,加载DLL,释放DLL等过程。而采用Dynamic Lib的方法,优点是容易理解和接受(因为他跟静态库的调用方法类似);缺点是修改了DLL工程的任何东西都需要使用最新的Dynamic Lib重新能编译Exe。

 

总结:

DLL和Lib是各有千秋,使用的情况也是各不相同,不过最终还是需要大家在项目中实践到底哪种方法好,到底采用哪种类型的库,总之,一切都要按需求最优。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

5条评论
  • 优弧

    2012 年 11 月 5 日 00:21

    来看看你,

    其它浏览器 其它操作系统
  • eliteYang

    2012 年 11 月 4 日 13:52

    @icedream: 我也接触不多

    其它浏览器 其它操作系统
  • icedream

    2012 年 11 月 4 日 11:49

    门外汉,但是和dll接触较多,像sevenzipsharp之类的

    活跃 其它浏览器 其它操作系统
  • Benxs

    2012 年 11 月 1 日 13:44

    这个贴代码的插件感觉很好用的样子呀。

    潜水 其它浏览器 其它操作系统
    1. eliteYang

      2012 年 11 月 1 日 15:19

      用的是crayon插件

      神话 其它浏览器 其它操作系统

发表评论

电子邮件地址不会被公开。 必填项已用*标注