mthoutai

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理


共同拥有两种库:
一种是LIB包括了函数所在的DLL文件和文件里函数位置的信息(入口)。代码由执行时载入在进程空间中的DLL提供,称为动态链接库dynamic link library。
一种是LIB包括函数代码本身。在编译时直接将代码增加程序其中,称为静态链接库static link library。
共同拥有两种链接方式:
动态链接使用动态链接库,同意可运行模块(.dll文件或.exe文件)仅包括在运行时定位DLL函数的可运行代码所需的信息。


静态链接使用静态链接库,链接器从静态链接库LIB获取全部被引用函数,并将库同代码一起放到可运行文件里。

关于lib和dll的差别例如以下:
(1)lib是编译时用到的,dll是执行时用到的。假设要完毕源码的编译。仅仅须要lib。假设要使动态链接的程序执行起来。仅仅须要dll。


(2)假设有dll文件,那么lib通常是一些索引信息,记录了dll中函数的入口和位置,dll中是函数的详细内容;假设仅仅有lib文件,那么这个lib文件是静态编译出来的。索引和实现都在当中。

使用静态编译的lib文件,在执行程序时不须要再挂动态库。缺点是导致应用程序比較大,并且失去了动态库的灵活性。公布新版本号时要公布新的应用程序才行。
(3)动态链接的情况下,有两个文件:一个是LIB文件。一个是DLL文件。

LIB包括被DLL导出的函数名称和位置。DLL包括实际的函数和数据。应用程序使用LIB文件链接到DLL文件。在应用程序的可运行文件里,存放的不是被调用的函数代码。而是DLL中对应函数代码的地址,从而节省了内存资源。DLL和LIB文件必须随应用程序一起发行。否则应用程序会产生错误。假设不想用lib文件或者没有lib文件。能够用WIN32 API函数LoadLibrary、GetProcAddress装载。

使用lib需注意两个文件:
(1).h头文件,包括lib中说明输出的类或符号原型或数据结构。应用程序调用lib时,须要将该文件包括入应用程序的源文件里。
(2).LIB文件,略。

使用dll需注意三个文件:
(1).h头文件,包括dll中说明输出的类或符号原型或数据结构的.h文件。应用程序调用dll时。须要将该文件包括入应用程序的源文件里。


(2).LIB文件。是dll在编译、链接成功之后生成的文件。作用是当其它应用程序调用dll时。须要将该文件引入应用程序,否则产生错误。假设不想用lib文件或者没有lib文件。能够用WIN32 API函数LoadLibrary、GetProcAddress装载。


(3).dll文件,真正的可运行文件,开发成功后的应用程序在公布时。仅仅须要有.exe文件和.dll文件,并不须要.lib文件和.h头文件。



使用lib的方法:
静态lib中,一个lib文件实际上是随意个obj文件的集合,obj文件是cpp文件编译生成的。在编译这样的静态库project时,根本不会遇到链接错误;即使有错,也仅仅会在使用这个lib的EXT文件或者DLLproject里暴露出来。
在VC中新建一个static library类型的projectLib,增加test.cpp文件和test.h文件(头文件内包含函数声明)。然后编译,就生成了Lib.lib文件。


别的project要使用这个lib有两种方式:
(1)在project->link->Object/Library Module中增加Lib.lib文件(先查询工程文件夹。再查询系统Lib文件夹);或者在源码中增加指令#pragma comment(lib, “Lib.lib”)。
(2)将Lib.lib拷入project所在文件夹。或者运行文件生成的文件夹,或者系统Lib文件夹中。


(3)增加对应的头文件test.h。

使用DLL的方法:
使用动态链接中的lib,不是obj文件的集合,即里面不会有实际的实现,它仅仅是提供动态链接到DLL所须要的信息,这样的lib能够在编译一个DLLproject时由编译器生成。
创建DLLproject的方法(略)。


(1)隐式链接
第一种方法是:通过project->link->Object/Library Module中增加.lib文件(或者在源码中增加指令#pragma comment(lib, “Lib.lib”)),并将.dll文件置入工程所在文件夹,然后增加相应的.h头文件。

#include "stdafx.h"
#include 
"DLLSample.h"

#pragma comment(lib, 
"DLLSample.lib")    //你也能够在项目属性中设置库的链接

int main()
{
        TestDLL(
123);   //dll中的函数。在DllSample.h中声明
        return(1);
}

(2)显式链接
须要函数指针和WIN32 API函数LoadLibrary、GetProcAddress装载,使用这样的加载方法,不须要.lib文件和.h头文件,仅仅须要.dll文件就可以(将.dll文件置入project文件夹中)。

#include <iostream>
#include 
<windows.h>         //使用函数和某些特殊变量
typedef void (*DLLFunc)(int);
int main()
{
        DLLFunc dllFunc;
        HINSTANCE hInstLibrary 
= LoadLibrary("DLLSample.dll");

        
if (hInstLibrary == NULL)
        
{
          FreeLibrary(hInstLibrary);
        }

        dllFunc 
= (DLLFunc)GetProcAddress(hInstLibrary, "TestDLL");
        
if (dllFunc == NULL)
        
{
          FreeLibrary(hInstLibrary);
        }

        dllFunc(
123);
        std::cin.
get();
        FreeLibrary(hInstLibrary);
        
return(1);
}


LoadLibrary函数利用一个名称作为參数,获得DLL的实例(HINSTANCE类型是实例的句柄),通常调用该函数后须要查看一下函数返回是否成功,假设不成功则返回NULL(句柄无效),此时调用函数FreeLibrary释放DLL获得的内存。


GetProcAddress函数利用DLL的句柄和函数的名称作为參数,返回对应的函数指针。同一时候必须使用强转;推断函数指针是否为NULL,假设是则调用函数FreeLibrary释放DLL获得的内存。此后,能够使用函数指针来调用实际的函数。
最后要记得使用FreeLibrary函数释放内存。



注意:应用程序怎样找到DLL文件?
使用LoadLibrary显式链接。那么在函数的參数中能够指定DLL文件的完整路径。假设不指定路径,或者进行隐式链接。Windows将遵循以下的搜索顺序来定位DLL:
(1)包括EXE文件的文件夹
(2)project文件夹
(3)Windows系统文件夹
(4)Windows文件夹
(5)列在Path环境变量中的一系列文件夹

posted on 2017-05-21 21:19  mthoutai  阅读(282)  评论(0编辑  收藏  举报