linux( 二)

来源:互联网 发布:sql注入攻击工具 编辑:程序博客网 时间:2024/05/21 10:52
回顾:        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目标指令
0 0
原创粉丝点击