一、gcc生成静态库和动态库
1.首先创建一个目录
接着在该目录下编写程序生成hello.h、hello.c、main.c,程序分别为
hello.h
#ifndef HELLO_H
#define HELLO_H
void hello(const char *name);
#endif //HELLO_H
hello.c
#include <stdio.h>
#include "hello.h"
void hello(const char *name)
{
printf("Hello %s!\n", name);
}
main.c
#include "hello.h"
int main()
{
hello("everyone");
return 0;
}
2.将hello.c文件编译成.o文件并使用ls命令进行查看
3.由.o文件创建静态库
静态库文件名的命名规范 lib为前缀,紧接着跟静态库名,扩展名为.a。例如:我们将创建的静态库名为 myhello,则静态库文件名就是 libmyhello.a。在创建和使用静态库时, 需要注意这点。创建静态库用 ar 命令。在系统提示符下键入以下命令将创建静态库文件libmyhello.a。
当看到生成.a文件时就生成成功了。
4.使用静态库
用 gcc 命令生成目标文件时指明静态库名,gcc 将会从静态库中将公用函数连接到目标文件中。
使用以下命令
gcc main.c libmyhello.a -o hello
最后删除静态库后看一下hello是否真的链接到目标文件中
发现确实是可以的
5.创建并使用动态库
动态库的后缀名为.so
我们要使用命令
gcc -shared -fPIC -o libmyhello.so hello.o
再进行查看是否生成了.so文件
这就说明生成动态库成功了
接着在程序中使用动态库,要用以下命令
gcc -o hello main.c -L. -lmyhello
但我们输入./hello后发现运行不起,这是因为运行行 hello程序时在在/usr/lib 中找不到该库文件,我们要输入以下命令
sudo mv libmyhello.so /usr/lib
将文件 libmyhello.so 移动到目录/usr/lib 中,这样就可以运行啦
二、静态库与动态库生成文件大小
1.编写一个x2x函数,一个x2y函数,main1函数代码将调用x2x和x2y,将这3个函数分别写成单独的3个 .c文件。并用gcc进行编译。
程序如下:
#ifndef MAIN1_H
#define MAIN1_H
float x2x(int a,int b);
float x2y(int a,int b);
#endif//MAIN_H
#include<stdio.h>
float x2x(int a,int b)
{
float c;
c=a+b;
return c;
}
#include<stdio.h>
float x2y(int a,int b)
{
float c;
c=a/b;
return c;
}
#include"main1.h"
#include"stdio.h"
int main()
{
int a,b;
float c,d;
scanf("%d%d",&a,&b);
c=x2x(a,b);
d=x2y(a,b);
printf("c=%f",c);
printf("d=%f",d);
return 0;
}
2.接着将x2x,x2y函数生成静态文件库并查看
ar -crv libmain1.a x2x.o x2y.o
3.用gcc将主函数的目标文件与静态库链接,生成可执行文件的大小。
gcc -shared -fPIC -o libmain1.so x2x.o x2y.o
gcc -o main2 main1.c libmain1.so
接着并用ls -la命令查看
4.使用命令生成动态库
gcc -shared -fPIC -o libmain1.so x2x.o x2
gcc -o main2 main1.c libmain1.so
过程与之前差不多,最后得出动态库的大小,可以发现,静态库比动态库小很多,生成的可执行文件大小也有差别。
三、gcc命令与as汇编编译器
1.gcc应用,按照书上的程序命令进行编译
先对程序进行一些预处理,预编,汇编,再查看一些大小属性之类的。
2.接着分析ELF文件
3.下载安装as汇编编译器
并对给出的程序hello.asm进行编译
最后程序运行正常。
程序如下:
再查看一下此文件的大小
四、第三方库函数
1.光标库(curses)的主要函数功能,curses函数库能够优化光标的移动并最小化需要对屏幕进行的刷新,从而也减少了必须向字符终端发送的字符数目。
清除屏幕:
int erase(void);//在屏幕的每个位置写上空白字符
int clear(void);//使用一个终端命令来清除整个屏幕,相当于vi内的Ctrl+L
//内部调用了clearok来执行清屏操作,(在下次调用refresh时可以重现屏幕原文)
int clrtobot(void);//清除光标位置到屏幕结尾的内容
int clrtoeol(void);//清除光标位置到该行行尾的内容
窗口移动和更新屏幕:
int mvwin(WINDOW *win, int new_y, int new_x); //移动窗口
int wrefresh(WINDOW *win);
int wclear(WINDOW *win);
int werase(WINDOW *win);
//类似于上面的refresh, clear, erase,但是此时针对特定窗口操作,而不是stdcur
int touchwin(WINDOW *win); //指定该窗口内容已改变、
//下次wrefresh时,需重绘窗口。利用该函数,安排要显示的窗口
int scrollok(WINDOW *win, bool flag); //指定是否允许窗口卷屏
int scroll(WINDOW *win); //把窗口内容上卷一行
移动光标:
int move(int new_y, int new_x); //移动stdcsr的光标位置
int leaveok(WINDOW *window_ptr,bool leave_flag);
//设置一个标志,用于控制在屏幕刷新后curses将物理光标放置的位置。
安装couses库
使用命令
sudo apt-get install libncurses5-dev
curses函数库的头文件和库文件就被分别安装在/usr/include/和/usr/lib/下
最后贪吃蛇游戏代码链接
http://www.linuxidc.com/Linux/2011-08/41375.htm
总结:在此次试验中,我清晰的感受到了一个程序的编译的全过程,并且自己亲手创建了静态库和动态库并比较大小,收获颇丰,感谢老师。