欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

动态库和静态库

程序员文章站 2022-06-09 17:41:51
...

首先纠正所谓“静态连接就是把需要的库函数放进你的exe之中”的说法。在真实世界中,有三个概念:Use static libary, static linked DLL, dynamic linked DLL. 多数人混淆了static libary 和 static linked DLL的概念,当然他们有似是而非的“相似之处”,比如都用到.lib,下面具体说明。

使用静态库(Use static libary)是把.lib和其他.obj一起build在目标文件中,目标文件可以是.exe,也可以是.dll或.oxc等。一般情况下,可以根本就没有“对应的”.dll 文件,如C Run Time(CRT)库。一个例子就是,写一个main(){},build出来并不是只有几个字节,当然有人会说那还有exe文件头呢?是,即使加上文件头的尺寸,build出的执行文件仍然“莫名的大”。实际上那多出来的部分就是CRT静态库。姑且可以把静态库.lib理解成外部程序的obj文件比较合理,它包含了函数的实现。

下面再谈static linked DLL 和 dynamic linked DLL又如何?

静态链接 (static linked DLL)从操作上在VC的Project|Settings…|Link (tab)|General (category)|Object/library modules 中设置和添加。比如要使用SDK中的PropertySheet() API, 就要在这里添加 comctl32.lib,然后再调用的源程序中#include

    {
        typedef BOOL (WINAPI *LPFNSHELLEXECUTEEX)(LPSHELLEXECUTEINFO);

        hShell32Dll = LoadLibrary(TEXT("SHELL32.DLL"));
        if (!hShell32Dll) { goto End; }

        lpfnShellExecuteEx = (LPFNSHELLEXECUTEEX)GetProcAddress(hShell32Dll,
            API_NAME(ShellExecuteEx));
        if (!lpfnShellExecuteEx) { goto End; }

        ...
        fOk = (*lpfnShellExecuteEx)(pShellExecuteInfo);
        ...
    End:
        if (hShell32Dll) {
            FreeLibrary(hShell32Dll);
        }
        lpfnShellExecuteEx = NULL;
        ...
    }

有人会想,动态链接这样麻烦,为什么还要用呢?这里有一个技术问题,对这个问题的解决直接导致了动态加载的需求。问题是有些DLL只在某个Windows版本中存在,或某个API只在某些Windows版本中被加入指定的DLL。当你使用静态链接的.exe试图在不支持的Windows版本上运行时,系统会弹出系统对话框提示某某.dll无法加载或无法定位某某API的消息,然后就中止.exe的运行。像这样因为个别功能的实现依赖于某个DLL,当这个DLL不可用时导致整个.exe无法运行是不明智的。避免这样的结局只有用动态链接。

再说一下,lib文件有两种:一种是与dll关联的,叫动态链接,使用生成之后是需要dll的,这种lib文件比较小;另一种是静态链接库,其他程序调用生成时会把其中的代码包含进来,不需要dll和lib,直接可以运行这种lib文件比较大,比dll要大。

相关标签: 动态库 静态库