• lib和dll的区别与使用


    抛出几个概念:库、静态库、动态库、链接、静态链接、动态链接、显示链接、隐式链接。

             若不明白,请继续往下看。

     

    什么是库

    :库是写好的现有的、成熟的、可以复用的代码。库和可执行文件的区别是:库不是独立程序,它是向其他程序提供服务的代码。

    有哪些库

    有两种库:静态库(.a、.lib)和动态库(.so、.dll),它们是两种共享程序代码的方式。

    静态库(Static library/Static link library):lib包含代码本身,在编译时直接将代码加入到程序当中。在可执行文件中包含了库代码的一份完整拷贝。vs编译成功后,只会生成一个.lib文件

    动态库(Dynamic library/Dynamic link library):lib包含了函数所在的dll和dll中函数位置的入口信息。代码由运行时加载在进程空间中的dll提供。vs编译成功后,会生成两个文件.lib文件和.dll文件

     

    静态库和动态库中的lib有什么区别

    静态库中的lib:包含函数代码本身(包括函数的索引和实现),在编译时直接将代码加入程序当中。

    动态库中的lib:包含函数所在的dll文件和文件中函数位置的索引,函数实现的代码由运行时加载到进程空间中的dll提供。

    所以:lib是编译时用到的,dll是运行时用到的。如果要完成代码的编译,只需要lib,如果要使动态链接的程序运行起来,只需要dll。

     

    链接的方式

    链接器将一个个目标文件(或许还有若干程序库)链接在一起生成一个完整的可执行文件。

    静态链接:使用静态链接库,链接器从静态链接库lib获取所有被引用函数,并将库同代码一起放到可执行文件中。

    动态链接:使用动态链接库,允许可执行模块(.dll文件或者.exe文件)仅包含在运行时定位dll函数的可执行代码所需的信息。

     

    隐式链接与显式链接

    隐式链接与显式链接是怎么回事呢?其实这两种链接方式只是dll的两种不同的加载方式而已。

    隐式链接:1.Property->Linker->Input->Additional Dependencies中添加.lib文件,或者在源代码中加入指令#pragma comment(lib,"XX.lib")

                      2. Property->Linker->Input->Additional Library Directories中配置.lib文件所在的相对路径 

                      3. 将.dll文件置入工程所在目录,然后添加对应的.h头文件

    显式链接:需要函数指针和WIN32 API函数:LoadLibrary、GetProcAddress装载,使用这种载入方式,不需要.lib文件和.h头文件,只需要.dll文件即可(将.dll文件放到工程目录中)。

     

    写一个静态库以及如何使用静态库:

    1.新建Win32 Project工程,Application type选择Static library类型。新建的工程中有stdafx.h和cpp,在上一篇博文中已介绍。

    2.这次就写一个支持加/减操作的lib,新增MyMath.h和MyMath.cpp。

     MyMath.h:
     1 #ifndef _MY_STATIC_LIB_H_
     2 #define _MY_STATIC_LIB_H_
     3 
     4 class MyMath
     5 {
     6 public:
     7     MyMath();
     8     ~MyMath();
     9 
    10     int Add(int nNumA, int nNumb);
    11     int Sub(int nNumA, int nNumb);
    12 };
    13 #endif // _MY_STATIC_LIB_H_
    View Code

    MyMath.cpp

     1 #include "stdafx.h"
     2 #include "MyMath.h"
     3 
     4 MyMath::MyMath()
     5 {
     6 }
     7 
     8 MyMath::~MyMath()
     9 {
    10 }
    11 
    12 int MyMath::Add(int nNumA, int nNumb)
    13 {
    14     return nNumA + nNumb;
    15 }
    16 
    17 int MyMath::Sub(int nNumA, int nNumb)
    18 {
    19     return nNumA - nNumb;
    20 }
    View Code

    接下来就新建一个exe工程,我们就取名:UseLibraryTest,该工程需要以下配置:

    1.属性C/C++->General->Additional Include Directories要配置MyMath.h文件所在的相对路径。

    2.属性Linker->General->Additional Library Directories要配置MyMath.lib文件所在的相对路径。

    3.属性Linker->Input->Additional Dependencies中添加MyMath.lib。这一步或者可以改为在使用该lib的工程cpp中添加:#pragma comment(lib, "MyMath.lib")

    4.最后在使用的cpp中添加#include <MyMath.h>

     1 #include "stdafx.h"
     2 #include <MyMath.h>
     3 #include <iostream>
     4 
     5 using namespace std;
     6 
     7 int main()
     8 {
     9     MyMath  MyMath;
    10     int     nNumA   = 10;
    11     int     nNumB   = 10;
    12     int     nResult = 0;
    13     
    14     nResult = MyMath.Add(nNumA, nNumB);
    15     cout << nResult << endl;
    16 
    17     nResult = MyMath.Sub(nNumA, nNumB);
    18     cout << nResult << endl;
    19 
    20     return 0;
    21 }
    View Code

     在第3步中,若改为用#pragma comment(lib, "MyMath.lib")的代码如下:

     1 #include "stdafx.h"
     2 #include <MyMath.h>
     3 #include <iostream>
     4 #pragma comment(lib, "Static Library.lib")
     5 
     6 using namespace std;
     7 
     8 int main()
     9 {
    10     MyMath  MyMath;
    11     int     nNumA   = 10;
    12     int     nNumB   = 10;
    13     int     nResult = 0;
    14     
    15     nResult = MyMath.Add(nNumA, nNumB);
    16     cout << nResult << endl;
    17 
    18     nResult = MyMath.Sub(nNumA, nNumB);
    19     cout << nResult << endl;
    20 
    21     return 0;
    22 }
    View Code

    如果第1步没有设置,则编译时会报错:fatal error C1083: Cannot open include file: 'MyMath.h': No such file or directory

    如果第2步没有设置,并且lib也没有在该工程目录的情况下,则链接时会报错:LINK : fatal error LNK1104: cannot open file 'Static Library.lib'

    如果第3步没有设置,会报错:

    1> UseLibraryTest.cpp
    1>UseLibraryTest.obj : error LNK2019: unresolved external symbol "public: __thiscall MyMath::MyMath(void)" (??0MyMath@@QAE@XZ) referenced in function _main
    1>UseLibraryTest.obj : error LNK2019: unresolved external symbol "public: __thiscall MyMath::~MyMath(void)" (??1MyMath@@QAE@XZ) referenced in function _main
    1>UseLibraryTest.obj : error LNK2019: unresolved external symbol "public: int __thiscall MyMath::Add(int,int)" (?Add@MyMath@@QAEHHH@Z) referenced in function _main
    1>UseLibraryTest.obj : error LNK2019: unresolved external symbol "public: int __thiscall MyMath::Sub(int,int)" (?Sub@MyMath@@QAEHHH@Z) referenced in function _main

    如果第4步没有做,会报错:error C2065: 'MyMath' : undeclared identifier等

    我举出这么多报错的情况,只是为了让你能够熟悉这些错误。如果有一天有这样的报错,就能够快速的定位。。多看看报错信息也是很重要的,以提高解决bug的能力。

    写一个动态库以及如何使用动态库:

    1.新建Win32 Project工程,Application type选择dll类型。新建的工程里面会发现比静态库多一个dllmain.cpp。
    2.同以上静态库一样,写一个支持加、减操作的dll。新增MyMath.h和MyMath.cpp。
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    SAP全球企业官孙小群的生活智慧
    C++ vs Python向量运算速度评测
    C++ Error: no appropriate default constructor available
    危险的浮点数float
    Vagrant 手册之 Vagrantfile
    MySQL 服务器性能剖析
    Vagrant 手册之多个虚拟机 multi-machine
    Vagrant 手册之同步目录
    Vagrant 手册之同步目录
    MySQL 中的 information_schema 数据库
  • 原文地址:https://www.cnblogs.com/LuckyAnnika/p/5008511.html
Copyright © 2020-2023  润新知