Linux 下的c++学习(二)

5 篇文章 1 订阅

1 c++静态库与动态库

   1.1 动机

            库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层 库。本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a、.lib)和动态库(.so、.dll)。

linux:  .a   .so-----库命名:libxxx.a/libxxx.so (xxx-库名)
window: .lib  .dll

      库制作:目的是为了提高代码复用率。同时可做代码保密。

      note: 开发完成后,提供给用户的文件只需要头文件(.h)与库文件即可(.a/.so)

      比较:

      1.  静态库:链接时与目标文件链接成可执行文件,缺点:每次用时需要拷贝一份占用内存,相对来说浪费资源。静态链接。

      2. 动态库:运行时链接载入库函数,只需要一份共享的库。节约资源。动态链接。

         静态链接: 在链接阶段,将源文件中用到的库函数与汇编生成的目标文件.o合并生成可执行文件。该可执行文件可能会比较大。多个程序调用会复制多份。这种链接方式的好处是:方便程序移植,因为可执行程序与库函数再无关系,放在如何环境当中都可以执行。

         动态链接: 多个程序共用一个库,这个目标文件在内存中只有一份,供所有程序使用。

并且在程序运行过程中动态调用库文件,很方便,又不占空间,但是动态链接有一个缺点就是可移植性太差。

2 静态库制作

        静态库的加载:链接阶段直接复制一份到链接阶段(参考一中c++执行过程)。

# 准备文件结构
├── include
│   └── head.h
    └── head.cpp
├── lib
│   └── libcalc.a
├── main.cpp
└── src
———head.cpp
# 1 生成目标文件(在include文件下执行)
g++ -c head.cpp -o head.o
# 2 制作静态库
ar rcs libcalc.a head.o 
# 制作完成后可以将libcalc.a拷贝到lib文件下
#3 运行测试静态库
 g++ main.cpp -o main -I ./include/ -l calc -L ./lib/
 # -I 查找 head.h头文件 -l 查找calc静态库(取libcalc后半部分),-L库位置。

note: vscode运行,需要添加库路径。

动态库制作# 备注,如果要在vscode运行,需要在task.json中添加head.h,head.cpp的路径。
"args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                /*******************添加库链接(添加路径需要自己添加)***************/
                "-I","/home/.../c++学习/lesson_2/calculate","/home/.../c++学习/lesson_2/calculate/head.cpp",
                /******************************************/
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
         动态库制作   ],

1.3 动态库制作

        动态库加载:运行时搜索共享库路径。

# 文件结构
├── calculate
│   ├── head.cpp
│   └── head.h
├── description.md
├── include
│   └── head.h
├── lib
│   └── libcalc.a #上面制作的静态库,可有可无
├── main.cpp
└── src
    └── head.cpp
# 1 生成目标文件(calculate文件下执行)
g++ -c -fpic head.cpp
# 2 制作动态库
g++ -shared *.o -o libcalc.so
#制作完成后可以将libcalc.so拷贝到lib文件下
# 3 动态库使用
g++ main.cpp -o main -I include/ -l calc -L lib/
#此时生成了main可执行文件
./main #执行,注意此时不能运行,问题在于程序main找不到库calc
#可以ldd查看动态依赖库
ldd main
# 解决方法,需要了解程序运行是寻找动态库的优先级(见上)。
# 推荐设置环境变量+/etc/设置cat /etc/ld.so.conf
# 环境变量对应三种,1)零时配置,终端关闭就消失。2 用户级配置(修改.bashrc),永久生效。3 系统级配置(修改profile)永久生效。
# 这里修改/etc..文件列表。

# 1 查看是否存在该文件,注意该文件为二进制文件,不可修改
ls /etc/ld.so.cache
# 修改配置文件
sudo vim /etc/ld.so.conf
# 在最后添加.so的局对路经
sudo ldconfig # 使生效
# 查看
cat /etc/ld.so.conf
# 此时可以运行及ldd查看。
./main
# 测试成功

1.4 附录:

#################head.h##############
#ifndef _HEAD_H
#define _HEAD_H
#include<iostream>

class Calc{
    public :
      Calc(int num1, int num2):a(num1),b(num2){};
      ~Calc(){};
      void add();
      void sub();
      void mul();
      void div();
    private:
       int a;
       int b;
};

#endif
####################head.cpp###################
#include<iostream>
#include"head.h"
using namespace std;

void Calc::add(){
    cout<<"a+b = "<<a+b<<endl;
}
cat /etc/ld.so.conf
void Calc::sub(){
    cout<<"a-b = "<<a-b<<endl;
}

void Calc::mul(){
    cout<<"a*b = "<<a*b<<endl;
}

void Calc::div(){
    if(b == 0){
        cout<<"error!"<<endl;
    }
    else
       cout<<"a/b = "<<a/b<<endl;
}
###########################main.cpcat /etc/ld.so.confp#################
#include<iostream>
#include"head.h"

using namespace std;cat /etc/ld.so.conf

int main(){
    Calc mycalculator(6,3);
    mycalculator.add();
    mycalculator.sub();
    mycalculator.mul();
    mycalculator.div();
    cout<<endl;
    return 0;cat /etc/ld.so.conf
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值