用gcc生成静态库和动态库,GCC编译器相关内容及Ubuntu学习opencv图像编程

一、用gcc生成静态库和动态库

(一)、hello实例使用库

1,创建目录
​​​​​​​​在这里插入图片描述
2、hello代码
在这里插入图片描述
hello.h
在这里插入图片描述
hello.c
在这里插入图片描述
main.c
在这里插入图片描述
3. gcc编译得到.o文件
在这里插入图片描述
4、创建静态库
在这里插入图片描述
5、程序中使用静态库
在这里插入图片描述 6、创建动态库
7、 在程序中执行动态库
8、静态库与动态库比较
在这里插入图片描述

(二)、实例1使用库

1、创建目录
在这里插入图片描述
2、代码
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3、程序中使用静态库
4、动态库的使用
在这里插入图片描述

(三)、实例2使用库

1、创建目录
在这里插入图片描述
2、代码
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3、静态库
在这里插入图片描述
4、动态库
在这里插入图片描述
  可执行文件通过编译链接获取得到,利用工具将源码编译得到.o文件,将.o文件链接得到可执行文件。一定要仔细编程,打错了好几个地方,仔细检查才好。

二、Linux GCC常用命令与GCC编译器背后的故事

(一)、Linux GCC常用命令

1、编写一个程序test.c
在这里插入图片描述
在这里插入图片描述
2、一步到位的编译指令是:

在这里插入图片描述
3、预处理,可以输出 test.i 文件中存放着 test.c 经预处理之后的代码。
4、编译为汇编代码,预处理之后,可直接对生成的 test.i 文件编译。
5、汇编,对于上一小节中生成的汇编代码文件。
6、连接,对于上一小节中生成的 test.o,将其与C标准输入输出库进行连接,最终生成程序 test。
在这里插入图片描述
7、多个程序编译

gcc test1.c test2.c -o test

  如果同时处理的文件不止一个,GCC 仍然会按照预处理、编译和链接的过程依次进行。如果深究起来,上面这条命令大致相当于依次执行如下三条命令:

gcc -c test1.c -o test1.o
gcc -c test2.c -o test2.o
gcc test1.o test2.o -o t

8、 检错

gcc -pedantic illcode.c -o illcode
gcc -wall illcode.c -o illcode
gcc -werror test.c -o test

9、库文件链接
编译成可执行文件

gcc -c -I /usr/dev/mysql/include test.c -o test.o

链接

gcc -L /usr/dev/mysql/lib -lmysqlclient test.o -o test

强制链接时使用静态链接库

gcc -L /usr/dev/mysql/lib -static -lmysqlclient test.o -o test

(二)、GCC编译器背后的故事

1,GCC:
  GCC(GNU C Compiler)是编译工具。本文所要介绍的将 C/C++语言编写的程序转换成为处理器能够执行的二进制代码的过程即由编译器完成。

2,Binutils:
  一组二进制程序处理工具,包括addr2line、ar、objcopy、objdump、as、ld、ldd、readelf、 size 等。这 一组工具 是开发和 调试不可 缺少的工具 ,分别简介如下:
  (1) addr2line:用 来将程序 地址转 换成其所 对应的程 序源文 件及所对 应的代 码行,也可以得到所对应的函数。该工具将帮助调试器在调试的过程中定位对应的源代码位置。
  (2) as:主要用于汇编,有关汇编的详细介绍请参见后文。
  (3) ld:主要用于链接,有关链接的详细介绍请参见后文。
  (4) ar:主要用于创建静态库。为了便于初学者理解,在此介绍动态库与静态库。

3, C 运行库:
  C 语言标准主要由两部分组成:一部分描述 C 的语法,另一部分描述 C 标准库。C 标准库定义了一组标准头文件,每个头文件中包含一些相关的函数、变量、类型声明和宏定义,譬如常见的 printf 函数便是一个 C 标准库函数,其原型定义在 stdio 头文件中。
  C 语言标准仅仅定义了 C 标准库函数原型,并没有提供实现。因此,C 语言编译器通常需要一个 C 运行时库(C Run Time Libray,CRT)的支持。C 运行时库又常简称为 C 运行库。与 C 语言类似,C++也定义了自己的标准,同时提供相关支持库,称为 C++运行时库。

4、准备工作代码
在这里插入图片描述
5、编译过程,预处理
在这里插入图片描述
6、将源文件 hello.c 文件预处理生成hehrllio.illio.i
在这里插入图片描述
在这里插入图片描述
7、GCC 的选项-E 使 GCC 在进行完预处理后停止hello.i 文件可以作为普通文本文件打开进行查看,其代码片段如下所示

extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# 942 "/usr/include/stdio.h" 3 4
# 2 "hello.c" 2
# 3 "hello.c"
int main(void)
{
printf("Hello World!" "\n");
return 0;
}

8、编译
在这里插入图片描述
9、 将预处理生成的 hello.i 文件编译生成汇编程序 hello.s。
在这里插入图片描述
10、 GCC 的选项-S 使 GCC 在执行完编译后停止,生成汇编程序。
hello.s 代码片段:

main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $.LC0, %edi
call puts
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc

11、汇编
在这里插入图片描述
12、 GCC 的选项-c 使 GCC 在执行完汇编后停止,生成目标文件。

13、链接
链接分为静态链接和动态链接
  (1) 静态链接是指在编译阶段直接把静态库加入到可执行文件中去,这样可执行
文件会比较大。链接器将函数的代码从其所在地(不同的目标文件或静态链接库中)拷贝到最终的可执行程序中。为创建可执行文件,链接器必须要完成的主要任务是:符号解析(把目标文件中符号的定义和引用联系起来)和重定位(把符号定义和内存地址对应起来然后修改所有对符号的引用)。
  (2) 动态链接则是指链接阶段仅仅只加入一些描述信息,而程序执行时再从系统中把相应动态库加载到内存中去
在这里插入图片描述
在这里插入图片描述
14、分析ELF文件

ELF 文件格式如下图所示,位于 ELF Header 和 Section Header Table
之间的都是段(Section)。一个典型的 ELF 文件包含下面几个段: .text:已编译程序的指令代码段。 .rodata:ro 代表
read only,即只读数据(譬如常数 const)。 .data:已初始化的 C 程序全局变量和静态局部变量。 .bss:未初始化的 C
程序全局变量和静态局部变量。 .debug:调试符号表,调试器用此段的信息帮助调试。

在这里插入图片描述

15、反汇编 ELF
在这里插入图片描述
使用 objdump -S 将其反汇编并且将其 C 语言源代码混合显示
在这里插入图片描述
在这里插入图片描述

三、综合实践

(一)、图片进行特效显示

1、创建一个代码存放文件夹 code ,然后进入文件夹中。
在这里插入图片描述
2、创建一个 test1.cpp 文件。
在这里插入图片描述
3、将给出的代码复制粘贴进去。test1.cpp。

4、在用同文件夹下准备一张图片,文件名为:lena.jpg。
在这里插入图片描述
5、执行以下命令:

gcc  test1.cpp  -o  test1  `pkg-config --cflags --libs opencv`

请解释这条编译命令,它是如何获得opencv头文件、链接lib库文件的路径的?

gcc + 文件名 + -o + 输出文件流名称 +` 支持包。

把gtk的头文件路径和库文件列出来,让编译去获取。–cflags和–libs分别指定头文件和库文件。
在这里插入图片描述
6、执行以下命令:./test1。
在这里插入图片描述

(二)、使用opencv库编写打开摄像头压缩视频

1、虚拟机获取摄像头权限

  • 使用快捷键 Win + R ,输入 services.msc ,并回车。
  • 找到 VMware USB Arbitration S… 服务,确保启动了。
  • 点击 “ 虚拟机 ” ,然后点击 “ 设置(S)… ”。
  • 选择 “ USB控制器 ” ,将 “ USB兼容性 ” 设置为 “ USB 3.0 ” ,并点击确定。
  • 选择 “ 虚拟机 ” ,再选择 “ 可移动设备 ” ,再选择 “ Quanta USB2.0 VGA UVC WebCam ” ,最后点击
    “ 连接 ” ,再弹出的窗口内点击 “ 确定 ” 。
  • 虚拟机右下角这个摄像头图标有个小绿点,则连接成功。

2、创建一个 test2.cpp 文件。
在这里插入图片描述
3、将给出代码复制粘贴进去。test2.cpp
  如果要求打开你硬盘上一个视频文件来播放,请问示例代码1第7行代码如何修改?
  VideoCapture capture(0),后面的参数设置为 0 ,则从摄像头读取视频并循环显示每一帧;如果设置为一个视频的文件名,比如:man.mp4 ,则会将视频读取并循环显示每一帧。

  在示例代码1第9行的while循环中,Mat是一个什么数据结构? 为什么一定要加一句waitKey延时代码,删除它行不行?
   while 循环体中的 Mat 数据结构其实是一个点阵,对应图像上的每一个点,点的集合形成了一帧图像。waitKey(30) ,中的参数单位是 ms 毫秒,也就是每一帧间隔 30 ms ,该语句时不能删除的,否则会执行错误,无法播放视频或录制视频。
在这里插入图片描述在这里插入图片描述
4、编译 test2.cpp 文件。
在这里插入图片描述
5、输出结果
在这里插入图片描述

四,Ubuntu系统中本地代码上传至Github库

1,创建SSH Key
这边直接创建一个新的SSH Key,在终端输入以下指令进行创建,其中 “xxxxxx@163.com” 是邮箱账号:

ssh-keygen -t rsa -C "xxxxxx@163.com"

2,在Github端设置SSH Key
  在Github网页界面,进入 “Setting->Personal settings->SSH and GPG keys”,点击 “New SSH Key”,其中title随便填写,另外一个是Key文本框内容,打开id_rsa.pub文件中的内容(即上图红框中描述的文件,可使用 “gedit” 指令打开),直接复制粘贴并点击 “Add SSH Key” 即可。
在这里插入图片描述
3,本地安装Git:输入以下指令

sudo apt-get install git

4,git初始化:在需要上传文件夹的根目录,打开终端并输入以下git指令进行初始化操作,这样即可将当前目录变成git可以管理的库

git init

5,添加需要上传的文件:输入以下指令,表示将整个文件夹内容都添加进去

git add ./

6,检查当前git状态:输入以下指令,查看当前分支及添加文件的情况

git status

7,commit推送:指令如下,其中 “-m” 后面内容表示添加的描述

git commit -m "first commit"

8,添加文件到远程库:进入刚所创建的github仓库,Clone with SSH
在这里插入图片描述

9,在终端输入以下指令

git remote add origin git@github.com:xxxx/xxx.git

10,Push上传:对本地仓库进行第一次push上传

git push origin master

11,上传成功
在这里插入图片描述

五,参考

HarrietLH的博客_CSDN博客-嵌入式,机器学习,网络编程领域博主
可乐有点好喝的博客_CSDN博客-FPGA新手入门,FPGA小项目领域博主
YFaris的博客_CSDN博客-操作系统,C++学习笔记,代码管理领域博主
Ubuntu系统中本地代码上传至Github库

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值