c++ 学习笔记(高级linux编程) day2

本文介绍了内存管理方法如brk/sbrk、mmap/munmap的不同应用场景,并详细讲解了GCC编译器的使用技巧及选项。同时,探讨了静态库与动态库的创建、使用方法及其优缺点。

回顾:

        brk/sbrk

        int brk(void *);

        void* sbrk(int);

        维护一个位置.brk/sbrk改变这个位置

                brk改变绝对位置

                sbrk相对改变位置;

                

        补充:全新的类型.

                永远记住: C的基本类型只有:整数(1字节(bool),2字节(char),4字节(int,int*)),小数(4字节,8字节)

                unsigned  signed

                所有的全新类型都是使用typedef重新定义.

                新的类型的C的原型.

                类型重定义的好处:

                            1.维护方便

                            2.移植

                            3.容易理解

                            


一. 映射虚拟内存

            没有任何额外的维护数据的内存分配

            mmap(分配)/umap(释放)

        

            1.函数说明

            void * mmap(void *start,//指定映射的虚拟地址  0 由系统指定开始位置

            size_t length,//映射空间大小  pagesize倍数

            int  prot , //映射权限 PROT_NULL PROT_READ PROT_WRITE  PROT_EXEC

            int flags,//映射方式

            int fd,//文件描述符号

            offset_t off );//文件映射的开始位置

         映射方式:

                 内存映射:匿名映射.

                 文件映射:映射到某个文件.只有文件映射时最后两个参数才有效.

                 

                 

                 MAP_ANONYMOUS 内存映射方式

                 MAP_SHARED  MAP_PRIVATE(二选一)

                 

                 

            

            2.案例

            3.总结

                选择什么样的内存管理方法?

                    STL

                    new

                    malloc(小而多数据)

                    brk/sbrk(同类型的大块数据,动态移动指针)

                    mmap/munmap(控制内存访问/使用文件映射)

            

            4.应用

二.编译工具与动态库

        1.gcc

                -o  文件名  重命名编译后的文件

                -O0 -O1  -O2  -O3 编译优化

                -g  -g0 -g1  -g2  -g3

              -Wall 显示所有警告

              -Werror  把所有警告当成错误

              -w 关闭警告

              -c 只编译不链接

              -E  预编译

              -S  汇编文件

              -D  在命令行定义宏.

                              在代码上定义宏

                              在命令行定义宏

              -x    指定编译的的语言类型

                      assemble

                      c

                      c++

                      

              gcc -x assemble test.s

              gcc -x     c test.c

              gcc -x c++ test.cpp

              

              -std =c89

              -std =c99  主函数返回int    

              int add(int * restrict a,int * restrict b);

              编译过程: -E  -S  -c

              ld  map.o  链接

              

              链接器一般都是自动调用连接器

              补充:

                  .c

                  .cpp

                  .CC

                  .h

                  .hpp

                  .o

                  .a

                  .so

                  .i  预编译文件

                  .s  汇编文件

        2.make

        3.gdb

        4.其他工具

        5.共享库

        

    三.静态库的编译

        1.编译过程(*.a  achieve)

                1.1 编译成目标文件

                        -static 可选

                        gcc -c -static 代码文件

                        

                        

                1.2 归档为静态库

                        ar工具

                            ar -r

                                 -t

                                 -p

                                 -x

                                 -m

                                 -q

                            ar -r 静态库文件  被归档的文件

                            ar -r ku.a  ku1.o  ku2.o

                            ar -t ku.a 查看库内文件

                        nm工具(查看函数符号表)

                            nm  静态库或者动态库或者目标文件或者执行文件

                            nm ku.a 查看归档文件

                1.3 使用静态库

                        gcc 代码 静态库

                        gcc callku.c  ku.a -o mainT

                        ./mainT

                        

                        使用静态库完成如下程序:

                                输入一个菱形半径,打印菱形.

                                输入整数封装成IOTool

                                菱形的打印封装成Graphics

                                计划:

                                        1.实现输入

                                        2.实现菱形

                                        3.编译静态库

                                        4.调用静态库

                            总结:

                                    1.什么是库?

                                            函数等代码封装的二进制已经编译的归档文件

                                    2.ar归档工具

                                    3.采用库的方式来管理代码优点:

                                            容易组织代码

                                            服用

                                            保护代码版权

                                    4.静态库的静态的含义:

                                         1.编译好的程序运行的时候不依赖库.库作为程序的一部分

                                                 编译连接

                                    5.静态库本质:

                                            目标文件集合(归档)

                                    6 -static 可选

                                    

------------------------------------------------

gcc -c -static ku1.c

gcc -c -static ku2.c


ar -r ku.a ku1.o  ku2.o


gcc  callku.c  ku.a  -o main


./main



------------------------------------------------

                                    

                                    

                                    

                2.库的规范与约定

                            库命名规则:

                                    lib.库名.a.主版本号.副版本号.主批次号

                                    lib库名.a

                            库使用规则

                            -l 库名

                            -L  库所在目录                                        

            ------------------------------------------------

            gcc -c -static ku1.c

            gcc -c -static ku2.c

            

            ar -r libdemo.a ku1.o  ku2.o

            

            

            gcc  callku.c  -o main -ldemo -L.

            

            

            ./main

            ------------------------------------------------        

                        

    

四.动态库的编译

            1.什么是动态库(共享库)

                        动态库是可以执行,静态库不能执行.

                        但动态库没有main,不能独立执行

                        动态库不会链接成程序的一部分.

                        程序执行的时候,必须需要动态库

            2.工具

                    ldd  查看程序需要调用的动态库

                    ldd  main

                    ldd只能查看可执行文件.

                    windows可执行文件格式 PE

                    linux可执行文件格式ELF

                

                            readelf -h  main      查看执行文件头

                            nm 查看库中的函数符号

            3.动态库的编译

                    1.编译

                        -c  -f pic(可选)  position  indepe code

                    2.链接

                        -shared

                        

            ----------------------------------------------------

            gcc -c -f pic ku1.c

            gcc -c -f pic ku2.c

            

            gcc -shared -o libdemo.so  ku1.o  ku2.o

            

            ----------------------------------------------------    

            4.使用动态库

                gcc  代码 动态库文件名

                gcc  代码  -o main  -l demo  -L .    // .表示当前目录

                

                

        问题:

                4.1 执行程序怎么加载动态库

                4.2 动态库没有作为执行程序的一部分,为什么连接器需要确定函数在

                        在动态库中的位置.

        

        动态库的加载:

                1.找到动态库

                2.加载动态库到内存空间

                3.映射到用户的内存空间

        动态库的查找规则:

                /lib

                /user/lib

                到环境变量LD_LIBRARY_PATH

                

                export LD_LIBRARY_PATH=.:~:..:~username

                

                缓冲机制:

                    把/lib:/usr/lib:LD_LIBRARY_PATH加载到缓冲区

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

            动态库的加载原理

            

            

                -------------------------------

                #include<dlfcn.h>

                

                main()

                {

                    void * handle=dlopen("./libdemo4.so",RTLD_LAZY);

                    void (*fun)(int) = dlsym(handle,"fun_name");

                    fun(5);

                    dlclose(handle);

                }

                

                

                gcc dldemo.c -o main -l dl  //加载dl库,不用加载libdemo4.so

                -------------------------------

                    动态库中函数的查找已经封装成库libdl.so

                    dlopen 打开一个动态库

                    dlsym  在打开的动态库中查找一个函数

                    dlclose 关闭动态库

                    dlerror 返回错误

                总结:

                    1.编译连接动态库

                    2.使用动态库

                    3.怎么配置让程序调用动态库

                    4.掌握某些工具的使用 nm ldd  lddconfig  

                                strip  删除多余信息

                                strip   libdemo.so

                                objdump


六.工具make的使用与makefile脚本

            

            背景:

                        make 编译脚本解释

                        

                        编译脚本Makefile

                        

                        make -f 脚本文件  目标

            

            脚本文件

                1.文本文件

                2.基本构成语法:

                            基本单位目标target:

                            目标名:依赖目标

                            目标名:依赖目标

                            \t;

-----------------------------------------//demo.mk

demo:

            @gcc iotool.c   -c -f pic  空格只能用tab

            gcc graphic.c  -c -f pic

            gcc iotool.0 graphic.c -shared -o libdemo.so

            gcc main -ldemo -o main -L. //直接编译链接一步到位

----------------------------------------

teminnal运行

        make -f demo.mk  demo

        


            

            



-----------------------------------------

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值