一.
1.阅读、理解和学习材料“用gcc生成静态库和动态库.pdf”和“静态库.a与.so库文件的生成与使用.pdf”,请在Linux系统(Ubuntu)下如实仿做一遍。
(1).创建一个目录保存文件并编写代码
hello.h
hello.c
main.c
(2).将hello.c编译成.o文件
(3).创建并使用静态库
创建:
工具:ar
静态库文件命名规范:以lib作为前缀,是.a文件
使用:
先生成main.o gcc -c hello main.c libmyhello.a
(4).创建并使用动态库
创建:
工具:gcc
动态库文件命名规范:以lib作为前缀,是.so文件
使用:
将libmyhello.so复制到目录/usr/lib中。
2.在第一次作业的程序代码基础进行改编,除了x2x函数之外,再扩展写一个x2y函数(功能自定),main函数代码将调用x2x和x2y ;将这3个函数分别写成单独的3个 .c文件,并用gcc分别编译为3个.o 目标文件;将x2x、x2y目标文件用 ar工具生成1个 .a 静态库文件, 然后用 gcc将 main函数的目标文件与此静态库文件进行链接,生成最终的可执行程序,记录文件的大小。
代码:
A1.c:
#include<stdio.h>
void print1(int arg)
{
printf("A1 print arg:%d\n",arg);
}
A2.c:
#include<stdio.h>
void print2(char *arg)
{
printf("A2 printf arg:%s\n",arg);
}
A.h:
#ifndef A_H
#define A_H
void print1(int);
void print2(char *);
#endif
test.c:
#include<stdio.h>
#include"A.h"
int main()
{
print1(1);
print2("test");
return(0);
}
静态库:
动态库:
3.将x2x、x2y目标文件用 ar工具生成1个 .so 动态库文件, 然后用 gcc将 main函数的目标文件与此动态库文件进行链接,生成最终的可执行程序,记录文件的大小,并与之前做对比。
sub1.c:
float x2x(int a,int b)
{
float c=0;
c=a+b;
return c;
}
sub2.c:
float x2y(int a,int b)
{
float c=0;
c=a/b;
return c;
}
sub.h:
#ifndef SUB_H
#define SUB_H
float x2x(int a,int b);
float x2y(int a,int b);
#endif
main.c:
#include<stdio.h>
#include"sub.h"
void main()
{
int a,b;
printf("Please input the value of a:");
scanf("%d",&a);
printf("Please input the value of b:");
scanf("%d",&b);
printf("a+b=%.2f\n",x2x(a,b));
printf("a/b=%.2f\n",x2y(a,b));
}
静态库:
动态库:
比较:静态库比动态库小
二.Gcc不是一个人在战斗。请说明gcc编译工具集中各软件的用途,了解EFF文件格式。学习任务如下:
阅读、理解和学习材料“Linux GCC常用命令.pdf”和“GCC编译器背后的故事.pdf”,如实仿做一遍。
1.常用命令
源码:
test.c
#include <stdio.h>
int main(void)
{
printf("Hello World!\n");
return 0;
}
2.编译器背后的故事
(1).创建目录并编写代码
hello.c
#include <stdio.h>
int main(void)
{
printf("Hello World! \n");
return 0;
}
编译过程:
预处理:gcc -E Hello.c -o Hello.i
编译:gcc -S Hello.i -o Hello.s
汇编:gcc -c Hello.s -o Hello.o
链接:
/**************/
gcc Hello.c -o Hello //使用动态库进行链接
size Hello //使用 size 查看大小
ldd Hello
/*************/
gcc -static Hello.c -o Hello //使用静态库进行链接
size Hello //使用 size 查看大小
ldd Hello
3.分析ELF文件
ELF 文件位于 ELF Header 和 Section Header Table 之间。
查看其各个 section 的信息:readelf -S Hello
反汇编ELF:
gcc -o Hello -g Hello.c
objdump -S Hello
三.(综合实践)每一个程序背后都站着一堆优秀的代码库。通过学习opencv图像库编程,了解如何借助第三方库函数完成一个综合程序设计。“学了opencv,妈妈再不担忧你不会图像编程啦!”。
在Ubuntu16/18系统下练习编译、安装著名的C/C++图像处理开源软件库 Opencv3.x (过程多,耗时长,需要耐心和细心)。安装成功后:
1. 编写一个打开图片进行特效显示的代码 test1.cpp(见opencv编程参考资料 );
注意gcc编译命令: gcc test1.cpp -o test1 `pkg-config --cflags --libs opencv`
创建test.cpp并编写代码:
1)请解释这条编译命令,它是如何获得opencv头文件、链接lib库文件的路径的?
pkg-config --cflags --libs opencv 是向程序提供相应库的路径信息,然后将输出的字符串作为结果给前面的可执行文件
2)改用make+makefile方式编译 上述程序(用变量命名格式写makefile文件,并包括 clean选项)
创建build文件夹:
mkdir build
cd build
使用make编译:
在build文件夹下进行:sudo make
2.练习使用opencv库编写打开摄像头压缩视频的程序。参考示例代码1和示例代码2。并回答:
1)如果要求打开你硬盘上一个视频文件来播放,请问示例代码1第7行代码如何修改?
将示例代码第7行代码中的VideoCapture capture(0)修改为VideoCapture capture("/home/opencv-3.4.11/K.mp4"),即:将0改为需要播放的视频名称以及它所存放的路径。
2)在示例代码1第9行的while循环中,Mat是一个什么数据结构? 为什么一定要加一句waitKey延时代码,删除它行不行?
while 循环体中的 Mat 数据结构其实是一个点阵,对应图像上的每一个点,每个图像都是由无数的点构成的,即Mat是一个图像矩阵。
waitKey()函数的参数单位是 ms 毫秒,其功能是不断刷新图像,如果没有这个就无法实现画面的实时显示,即看不到画面的变化。所以删除waitKey不行。
3)示例代码1代码会在while循环中一直运行,你如果试图用鼠标关闭图像显示窗口,会发现始终关不掉。需要用键盘Ctrl+C 强制中断程序,非常不友好。如何改进?
增加一个判断语句,来进行关闭。