linux( 二)

回顾:
        brk/sbrk
        int brk(void *p);
        void *sbrk(int);

        维护一个位置。brk/sbrk改变这个位置
                    brk改变绝对位置。
                    sbrk相对改变位置。

        补充:全新的类型。
                    永远记住:c的基本类型就:整数(1,2,4),小数(4,8)
                    unsigned signed
                    所有全新类型都是使用typedef重新定义。
                    新的类型的C的原型。
                    类型重定义的好处:
                            1.维护方便
                            2.移植
                            3.容易理解


一.映射虚拟内存
        没有任何额外维护数据的内存分配。
        mmap(分配)/unmap(释放)
        1.函数说明
        void *mmap(
            void *start,//指定映射的虚拟地址 0由系统指定开始位置)
            size_t length,//映射空间大小 pagesize倍数
            int prot,//映射权限  PROT_NONE | PROT_READ PROT_WRITE PROT_EXEC
            int flags,//映射方式
            int fd,//文件描述符号
            offset_t off);//文件中的映射开始位置(必须是pagesize的倍数)

            映射方式:
                    内存映射:匿名映射。
                    文件映射:映射到某个文件
                                      只有文件映射最后两个参数有效。

                    MAP_ANONYMOUS 
                    MAP_SHARED   MAP_PRIVATE(二选一)

        2.案例                
        3.总结
选择什么样的内存管理方法?
        智能指针(指针池)
        STL         
        new     
        malloc (小而多数据) 
        brk/sbrk (同类型的大块数据,动态移动指针)
        mmap/munmap(控制内存访问/使用文件映射/控制内存共享)       
        4.应用    

二.编程工具与动态库
    1.gcc
            -o  输出文件名
            -O  -O0 -O1 -O2 -O3  编译优化
            -g  -g0 -g1 -g2 -g3  产生调试信息
            -W  all  error   
            -Wall  显示所有警告  
            -Werror   把警告当错误
            -w  关闭警告



            -c  只编译不连接
            -E  预编译
            -S  汇编

            -D  在命令行定义宏。
                        在代码中定义宏
                        在命令行定义宏

            -x  指定编译的语言类型
                    c++
                    c
                    .S
                    none 自动判定
            -std=C89
                     C99



        编译过程:-E  -c -S   自动调用连接器
        连接器 ld
        补充:
                .c
                .cpp
                .CC
                .h
                .hpp
                .o
                .a
                .so
                .i    预编译文件
                .s      汇编文件    

三.静态库的编译
        1.编译过程(*.a   achieve)
            1.1.编译成目标文件
                    -static  可选
                    gcc -c -static 代码文件.c

            1.2.归档成静态库
                    ar工具
                            ar -r
                                 -t
                        ar -r 静态库文件  被归档的文件     

                    nm工具(察看函数符号表)
                        nm 静态库或者动态库或者目标文件或者执行文件
            1.3.使用静态库
                    gcc 代码  静态库             

        使用静态库完成如下程序:
                    输入一个菱形半径,打印菱形。
                    输入整数封装成IOTool
                    菱形的打印封装成Graphics
                    计划:
                            1.实现输入
                            2.实现菱形
                            3.编译静态库
                            4.调用静态库
        总结:
                1.什么是库?
                        函数等代码封装的二进制已经编译的归档文件
                2.ar归档工具
                3.采用库德方式管理代码优点:
                        容易组织代码
                        复用
                        保护代码版权
                4.静态库的静态的含义:
                        编译好的程序运行的时候不依赖库。
                        库作为程序的一部分编译连接。
                5.静态库本质:
                        就是目标文件集合(归档)
                6.-static可选

         2.库的规范与约定                              
                    库命名规则:
                            lib库名.a.主版本号.副版本号.批号
                            lib库名.a
                    库使用规则
                            -l 库名
                            -L 库所在目录                


四.动态库的编译
            1.什么是动态库?(共享库)
                    动态库是可以执行,静态库不能执行
                    但动态库没有main,不能独立执行。
                    动态库不会连接成程序的一部分。
                    程序执行的时候,必须需要动态库文件。
            2.工具
                    ldd  察看程序需要调用的动态库
                            ldd 只能察看可执行文件.
                    readelf -h 察看执行程序头.
                    nm   察看库中的函数符号
            3.动态库的编译
                    3.1.编译
                            -c -fpic(可选)
                    3.2.连接
                            -shared
            4.使用动态库
                    gcc 代码 动态库文件名 
                    gcc 代码   -l库名 -L动态库所在路径

            标准命名规则:
                    lib库名.so
                    lib库名.a

                    -l 库名  -L 库所在路径

            问题:
                    4.1.执行程序怎么加载动态库?
                    4.2.动态库没有作为执行程序的一部分,为什么连接需要指定动态库以及目录?
                            连接器需要确定函数在动态库的中的位置

            动态库的加载:
                    1.找到动态库
                    2.加载动态库到内存
                    3.映射到用户的内存空间
            系统对动态库查找规则:
                    /lib
                    /usr/lib
                    到环境变量LD_LIBRARY_PATH指定的路径中查找
            缓冲机制:
                    把/lib:/usr/lib:LD_LIBRARY_PATH加载到缓冲。

                    /sbin/ldconfig -v 刷新缓冲中so的搜索数据

    综合应用:
            输入两个数,计算两个数的和。
            要求:输入与计算两个的数的和封装成动态库调用

五.使用libdl.so库
        动态库加载的原理                                                

        动态库中函数的查找已经封装成库libdl.so
        dlopen  打开一个动态库
        dlsym       在打开动态库找一个函数
        dlclose 关闭动态库
        //dlerror 返回错误

总结:
        1.编译连接动态库
        2.使用动态库
        3.怎么配置让程序调用动态库
        4.掌握某些工具的使用:nm ldd lddconfig
                            objdump  
                            strip  去掉多余的信息.

六.工具make的使用与makefile脚本
    背景:
            make 编译脚本解释

            编译脚本Makefile

            make -f  脚本文件  目标

    脚本文件
            1.文本文件
            2.基本构成语法:
                    基本单位目标target
                    目标名:依赖目标
                        \t目标指令
                        \t目标指令
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值