静态链接库和动态链接库

来源:互联网 发布:方正兰亭纤黑简体 mac 编辑:程序博客网 时间:2024/06/05 10:36

静态链接库(Static Library)和动态链接库(Dynamic Linked Library)


一、静态链接库与动态链接库区别

      它们都是共享代码的方式,主要区别:

1、采用静态链接库,则lib中的指令全部被直接包含在最终生成的exe文件中;采用动态链接库,exe文件在执行时可以“动态”地引用和卸载dll文件,exe与dll相互独立。

2、静态链接库中不能再包含其他静态链接库或动态链接库;而动态链接库中还可以再包含。

3、如果当前工程有多处对dll文件中同一个函数的调用,那么执行时该函数只会留下一份拷贝;如果有多处对lib文件中同一函数的调用,那么该函数将在当前程序的执行空间中留下多份拷贝,即一处调用产生一份拷贝。


导入库(ImportLibrary):

       使用动态链接库时,往往提供两个文件:一个导入库和一个dll。导入库包含被dll导出的函数和变量的符号名,dll包含实际的函数和数据。在编译链接可执行文件时,只需要链接导入库,dll中的函数代码和数据并不复制到可执行文件中,在运行的时候,再去加载dll,访问dll中导出的函数。

       导入库方便程序静态载入动态链接库,否则你可能就需要自己LoadLibrary调入DLL文件,然后再手工GetProcAddress获得对应函数了。有了导入库,你只需要链接导入库后按照头文件函数接口的声明调用函数就可以了


静态库和导入库区别:

       虽然它们后缀都为.lib,但实质完全不同。静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。

PS:以上区别,采用了windows格式以方便描述。

 


二、静态链接库和动态链接库生成

文件格式:

静态链接库:.lib(windows),.a(linux等平台)

动态链接库:.dll(windows),.so(linux等平台)

 

静态链接库生成:

       创建静态链接库比较简单,创建win32控制台程序,选择静态库。生成工程以后就像定义一般的函数般,定义放在头文件,然后实现放在cpp文件里头,直接build就出来一个静态的lib了,发布时附上头文件给使用者就可以。

动态链接库生成:

       选择新建一个Win32Dynamic-Link Library。需要建立一个c/c++ head file和一个c/c++ source file并加入工程。头文件中内容为输出函数的声明,源文件中内容为DllMain函数和输出函数的定义。

       如:define LIBSHARED_EXPORT __declspec(dllexport)

              extern "C"LIBSHARED_EXPORT ITest* TestAPI();

PS:本文只说明windows平台创建静态链接库和动态链接库方法,跨平台构建可以使用cmake,后续介绍。


三、静态链接库和动态链接库使用

静态链接:

#pragmacomment(lib, “test.lib”)

静态库的链接可以使用静态链接,动态链接库也可以使用这种方法链接导入库。


动态链接

1、typedef函数原型和定义函数指针,如:

      typedef ITest* (*DLLFUN)(void);。

2、载入dll,保存dll实例句柄,如:

      HINSTANCE dllHandle = LoadLibrary(libPath.c_str());(windows)

      void * dllHandle =dlopen(libPath, RTLD_LAZY | RTLD_LOCAL);(linux等平台)

3、得到dll中函数的指针,如:

      void* funcAddress =GetProcAddress((HINSTANCE) dllHandle, funcName); (windows)

      void* funcAddress =dlsym((void*) dllHandle, funcName); (linux等平台)

      DLLFUN  Dll_clFun = (DLLFUN) funcAddress;

      ITest * m_testAPI = (ITest *)Dll_clFun();

      动态库就是在需要调用其中的函数时,根据函数映射表找到该函数然后调入堆栈执行。

4、使用完毕,卸载dll,如:

      FreeLibrary((HINSTANCE) dllHandle); (windows)

      dlclose((void*)dllHandle);(linux等平台)

 


0 0