动态链接库

动态链接库是什么,为什么要用动态链接库

dll是文件,是二进制文件,是可执行文件。所谓可执行文件就是可以控制OS执行的,其实就是一堆CPU指令。但是dll不是能被windows直接执行,其实CPU是可以执行任何有效指令的,windows不能直接执行是因为windows的shell可以直接实行*.exe文件,没有必要在多一个*.dll。既然已经有可以直接执行的*.exe了,那么为什么要有可间接执行的*.dll呢?原因很多:

  1. 由于每个exe是运行都是一个进程,而进程之间是有严格的界限的,这样就产生了一个问题,很多很多的程序里面包括了一些相同功能的函数,尽管进程地址空间都是独立的,但为每个程序文件链接相同的代码显然是一种浪费。
  2. 我们都知道软件开发的一个重要原则就是模块相对独立,接口清晰。为此,我们在编写源文件时使用很多方法,不管是C语言众多的头文件和源文件,还是C++的类封装,这还专门有一门学问叫做《设计模式》,这种种都是为了两个字——清晰!然而最后编译链接的成果就是一个exe文件,显然这是和软件设计相悖的。dll很好地解决了这个问题,一个dll是一个相对独立的模块,当程序只需要改动一个模块时,只要替换一个新的dll。只要设计的好,dll间也存在层次结构,那么更新一套软件就可以精确地定位模块,到底需要替换多少dll。

动态链接库怎么用

dll主要有两种用法:

  1. 一般编译器在编译链接dll时,会有两个产物,一个lib(静态链接库),一个dll。lib用于将.h文件中声明的函数定位到dll。这样,使用时就只要把.h .lib添加到工程(VC),直接使用函数名引用函数,编译器遇到这样的函数调用时会让它通过编译,因为.lib在链接时说明了“该函数再某个dll中”^_^
  2. 没有.h和.lib文件时,一样可以引用dll中的函数,如果知道函数原型,那么LoadLibrary和GetProcAddress可以得到函数的指针,然后就可以调用
  3. 调用M$未公开的函数,SDK开发包介绍了大量函数,但并不是全部,依然有相对部分函数是没有文档说明的,一般是微软内部使用的。然而有时一些特殊的用途,我们需要调用未公开函数。再开发VxD时,就经常要调用kernel32.dll中的未公开函数
  4. OpenVxDHandle
    ...
        HMODULE   hKernelModule;   
        HANDLE    hEvent;   
        DOWRD     KernEvent;  
        hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);   
        hKernelModule=::LoadLibrary("KERNEL32.DLL");   
        if(hKernelModule==NULL)
        {
            return   NULL;   
        }   
        OpenVxDHandler=(OPENVXDHANDLE)GetProcAddress(hKernelModule,"OpenVxDHandle");   
        if(OpenVxDHandler==NULL)
        {   
            FreeLibrary(hKernelModule);   
            return   NULL;   
        }   
        KernEvent=(*OpenVxDHandler)(hEvent);   
        FreeLibrary(hKernelModule);       
  5. 有的函数再dll中没有名字,这也是可以调用的,因为没有名字会有一个标识的ID,调用时在以上步骤中GetProcAddress的第二个参数用MAKEINTRESOURCE宏转换一下
      ...
     
  6.   typedef void (WINAPI* RUN)(HWND, HICON, LPCSTR, LPCSTR, LPCSTR, UINT);
        HMODULE hShell32;
        RUN RunFileDlg;
        hShell32 = LoadLibrary("shell32.dll");
        RunFileDlg = (RUN)GetProcAddress(hShell32, MAKEINTRESOURCE(61));
        RunFileDlg(hParent, hIcon, NULL, NULL, NULL, 0);
        FreeLibrary(hShell32); 
    这段代码就是去调用shell的运行对话框
原文地址:https://www.cnblogs.com/iwasmu/p/1491804.html