静态链接库与动态链接库

来源:互联网 发布:python 查看字节码 编辑:程序博客网 时间:2024/06/05 19:47


链接库总共包括两种:

一种是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库的创建方法

1.创建工程时直接选择lib库

2.工程属性—配置属性—常规—配置类型中选lib库

之后生成,默认在debug目录下生成lib文件,在工程同名文件夹下有相应的头文件

lib库的使用

1.项目-属性-配置属性-VC++目录-包含目录中添加头文件所在目录

2.VC++目录-库目录添加lib文件所在路径

3.在链接器-输入-附加依赖项中添加lib

注意在编写程序时添加头文件


dll的创建

1.创建工程时直接选择dll库

2.工程属性—配置属性—常规—配置类型中选dll库

3.DLL中导出函数的声明有两种方式:

一种为在函数声明中加上  _declspec(dllexportint add(int a, int b);

对于C的编译器需要添加 extern "C" _declspec(dllexportint add(int a, int b);

另外一种方式是采用模块定义(.def) 文件声明

def文件的编写

def文件必须包含两个部分LIBRARY和EXPORTS

例子:

LIBRARY DllTestDef

EXPORTS 

Add @ 1

Sub @ 2

def文件的规则为:

  (1)LIBRARY 后面列出def文件相应的DLL名;

  (2)EXPORTS语句后列出要导出函数的名称。可以在.def文件中的导出函数名后加@n,表示要导出函数的序号为n(在进行函数调用时,这个序号将发挥其作用);@后的序号不给出的话系统会自动给出。

def文件的设置

链接器—输入—模板定义文件,若使用VS添加的def则会自动把def添加进去

创建def文件之后,生成,默认在debug目录下生成dll文件与lib文件,在工程同名文件夹下有相应的头文

dll文件的使用

(1)隐式链接

      与lib库的使用相同

       1.项目-属性-配置属性-VC++目录-包含目录中添加头文件所在目录

       2.VC++目录-库目录添加lib文件所在路径

       3.在链接器-输入-附加依赖项中添加lib

       注意经测试这种情况程序只需要lib,与dll无关?

(2)显式链接

显示链接不需要.h与.lib文件,只需要dll文件,将其放在你的工程文件中即可

#include <windows.h>        typedef void (*DLLFunc)(int);int main(){        DLLFunc dllFunc;        HINSTANCE hInstLibrary = LoadLibrary("test.dll");//添加你的dll        if (hInstLibrary == NULL)        {          FreeLibrary(hInstLibrary);        }        dllFunc = (DLLFunc)GetProcAddress(hInstLibrary, "TestDLL");//添加你要运行的函数名        if (dllFunc == NULL)        {          FreeLibrary(hInstLibrary);        }        dllFunc(123);//以其作为函数名直接调用函数}

LoadLibrary函数利用一个名称作为参数,将dll加载置内存中,获得DLL的实例(HINSTANCE类型是实例的句柄),通常调用该函数后需要查看一下函数返回是否成功,如果不成功则返回NULL(句柄无效),此时调用函数FreeLibrary释放DLL获得的内存。
GetProcAddress函数利用DLL的句柄和函数的名称作为参数,返回相应的函数指针,同时必须使用强转;判断函数指针是否为NULL,如果是则调用函数FreeLibrary释放DLL获得的内存。此后,可以使用函数指针来调用实际的函数,最后使用FreeLibrary函数释放内存。

注意:应用程序如何找到DLL文件?
使用LoadLibrary显式链接,那么在函数的参数中可以指定DLL文件的完整路径;如果不指定路径,或者进行隐式链接,Windows将遵循下面的搜索顺序来定位DLL:

(1)包含EXE文件的目录

(2)工程目录

(3)Windows系统目录

(4)Windows目录

(5)列在Path环境变量中的一系列目录








0 0
原创粉丝点击