寒假学习 第四、五天 (linux 高级编程)

原创 2014年01月18日 22:03:29

寒假学习 第四、五天 (linux 高级编程) 笔记 小结

一、映射虚拟内存

mmap / unmap          


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(二选一)

列子:
#include<stdio.h>
#include<unistd.h>
#include<sys/mman.h>
#include<stdlib.h>

int main()
{
	int *p = mmap(
		NULL,
		getpagesize(),     //一个页的大小
		PROT_READ|PROT_WRITE,
		MAP_ANONYMOUS|MAP_SHARED,
		0,0);
	*p = 0;
	*(p+1) = 1;
	*(p+2) = 2;
	*(p+3) = 3;

	printf("%d\n",p[2]);
	printf("%p\n",p);
	printf("%p\n",p+1);
	printf("%p\n",p+2);
	printf("%p\n",p+3);
	munmap(p,getpagesize());
	return 0;
}




二、编译工具

1.gcc

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
                assembler 汇编
		none 自动判定
	-std=C89
	     C99



编译过程:-E  -c -S   自动调用连接器
连接器是 ld
注意 gcc只是编译器   链接是用ld



三、静态库


什么是静态库

     函数等代码封装的二进制已经编译的归档文件
     本质就是目标文件集合(归档)
     静态是指编译好的程序运行的时候不依赖库,库作为程序的一部分编译连接

采用静态库方式管理代码优点

      容易组织代码
      复用
      保护代码版权

静态库的编译

  
   1.编译
      gcc -c -static  xxx.c    其中    -static 是可选的
   2.归档成静态库
      ar  -r   xxx.a  xxx.o  xxx.o     xxx.a  就是静态库文件
      ar是一个归档工具 
   3.使用静态库
      方式1:   gcc  xxx.c  xxx.a  -oxxx
      方式2:   把静态库文件的名子写成  lib库名.a(lib库名.a.主版本号.副版本号.批号) 
                        用   gcc  xxx.c -l  库名 -L 库所在的位置

nm工具

   可以察看函数符号表
   nm 静态库或者动态库  或   者目标文件    或   者执行文件



列子:
root@/codes/day04# ar -r libku.a add.o sub.o
root@/codes/day04# gcc main.c -omain -lku -L .


四、动态库(共享库)

什么是动态库,跟静态库的区别

        
        动态库是可以执行,静态库不能执行
但动态库没有main,不能独立执行。
动态库不会连接成程序的一部分。
程序执行的时候,必须需要动态库文件。

工具

       ldd  可执行文件
             查看程序需要调用的动态库,只能加可执行文件(动态库文件也是可执行文件)
       readelf  -h   可执行文件
              linux 下可执行文件格式是elf  ,readelf  -h 可用来察看执行程序头

动态库的编译

     gcc  -c -fpic  xxx.c        -fpic  可不用写
     gcc  -shared  -oxxx.so   xxx.c   xxx.c        xxx.so 就是动态库文件

使用动态库

     方法1:gcc xxx.so  xxx.c  -oxxx

     方法2: lib库名.so     gcc xxx.c -l 库名  -L 库所在路径

      这样编译出来的可执行文件还是会出错的,会出现找不到  lib库名.so,要改环境变量LD_LIBRARY_PATH
     (不要忘记加上export )或直接把lib库名.so 放到 /lib /user/lib  等

      方法3:使用libdl.so库 直接在代码加载动态库

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

列子:
#include<stdio.h>
#include<unistd.h>
#include<dlfcn.h>

int main()
{
	void *handle = dlopen("./libku2.so",RTLD_LAZY);
	int (*add)(int,int) = dlsym(handle,"add");
	int (*sub)(int,int) = dlsym(handle,"sub");
	int r = add(55,22);
	int s = sub(55,22);
	dlclose(handle);
	printf("%d %d\n",r,s);
	printf("%d\n",getpid());
	while(1);
	return 0;
}
编译  gcc main.c -omain -ldl

这样在运行就 不用改环境变量 编译时也 -l 指定 上面的 ku2 
但 要指定 libdl.so   加上  -ldl


   

五、其他知识点


restrict   
只能是用在 函数参数指针上的
优化函数参数的寻址过程,提供运行速度
 
register
修饰普通变量
表示这个数据要保存在寄存器中


readelf  -h  查看执行文件的头

nm  查看库中的函数符号

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

objdump    有点像那个快速查看之类的工具,就是以一种可阅读的格式让你更多地了解二进制文件可能带有的附加信息。

strip  去掉多余信息

版权声明:本文为博主原创文章,未经博主允许不得转载。

寒假学习 第一天 (linux 高级编程)

寒假学习 day01 笔记 linux 高级编程 linux 内存管理  1.    linux 每运行一个程序都会在/proc内生成一个跟自己pid一样的文件夹,你面放着程序有关的信息 ...

寒假学习 第20天 (linux 高级编程)

寒假学习 第20天 (linux 高级编程) 笔记总结 一、sigqueue/sigaction 1. 信号中断函数是否被其他信号中断?    信号函数调用中只屏蔽本身信号,不屏蔽其他信号...

寒假学习 第25天 (linux 高级编程)

寒假学习 第25天 (linux 高级编程) 笔记总结 一、信号量(进程同步) 模型 (1)创建或者得到信号量     semget        int semget(key_t key,...

寒假学习 第七、八天 (linux 高级编程)

寒假学习 第七、八天 (linux 高级编程) 笔记 小结 一、IO基础 1.认识内核对象             系统不允许程序直接访问设备和内存,但可以通过内核系统函数去访问,系统对每个内核对...

寒假学习 第24天 (linux 高级编程)

寒假学习 第24天 (linux 高级编程) 笔记总结 一、基于socket文件的IPC 两种模型:         对等模型          C/S模型 1. 对等模型     绑定 ...

寒假学习 第22、23天 (linux 高级编程)

寒假学习 第22、23天 (linux 高级编程) 笔记总结 一、基于内存的通信 一组内核共享工具 ipcs 可以看到三段东西 Shared Memory Segments  共享内存 Se...

寒假学习 第12天 (linux 高级编程)

寒假学习 第12天 (linux 高级编程)  笔记 总结 curses 接着前天 6.字符属性与颜色 判定终端是否支持颜色 bool has_colors();//都支持颜色,建议不判定 初始...

寒假学习 第13,14天 (linux 高级编程)

寒假学习 第13天 (linux 高级编程)  笔记 总结 一、IO与文件目录管理 1.pread与lseek+read的区别    pread读取后不会改变读写位置 2.mmap映射     /...

寒假学习 第三天 (linux 高级编程)

寒假学习 第三天 (linux 高级编程) 笔记 小结 一、虚拟内存的分配  int brk(void *addr);                           分配空间,释放空间    ...

寒假学习 第11天 (linux 高级编程)

一、curses 1.简介: CUI字符界面,GUI:图形界面 curses就是cui的库 老版本libcurses.so,新版本libncurses.so printf / scanf 等标...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:寒假学习 第四、五天 (linux 高级编程)
举报原因:
原因补充:

(最多只允许输入30个字)