一、用gcc生成静态库和动态库
函数库分为静态库和动态库。
- 静态库
在程序编译时会被连接到目标代码中,程序运行是则不需要静态库的存在。 - 动态库
在程序编译时不会被连接到目标代码中,而是程序运行时载入的。
两者区别:前者是编译连接的,后者是程序运行载入的。
(一)hello实例使用库
1.准备过程
(1). 创建一个目录
(2). hello代码
hello.h

hello.c

main.c

(3). gcc编译得到.o文件
gcc -c hello.c

2. 静态库使用
(1)创建静态库
创建静态库的工具:ar
静态库文件命名规范:以lib作为前缀,是.a文件
ar -crv libmyhello.a hello.o
(2)程序中使用静态库
①gcc -o hello main.c -L. -lmyhello
②gcc main.c libmyhello.a -o hello
③先生成main.o gcc -c main.c
生成可执行文件 gcc -o hello main.c libmyhello.a
(3)验证静态库的特点
在删掉静态库的情况下,运行可执行文件,发现程序仍旧正常运行,表明静态库跟程序执行没有联系。同时,也表明静态库是在程序编译的时候被连接到代码中的。
3.动态库的使用
(1). 创建动态库
创建动态库的工具:gcc
动态库文件命名规范:以lib作为前缀,是.so文件
gcc -shared -fPIC -o hello.o shared:表示指定生成动态链接库,不可省略
-fPIC:表示编译为位置独立的代码,不可省略

(2). 在程序中执行动态库
gcc -o hello main.c -L. -lmyhello或gcc main.c -o hello
再运行可执行文件hello,会出现错误

问题的解决方法:将复制到目录/usr/lib中。由于运行时,是在/usr/lib中找库文件的。
mv /usr/lib

4.静态库与动态库比较
gcc编译得到.o文件 gcc -c hello.c
创建静态库 ar -crv libmyhello.a hello.o
创建动态库 gcc -shared -fPIC -o hello.o
使用库生成可执行文件 gcc -o hello main.c -L. -lmyhello
执行可执行文件 ./hello

在执行可执行文件,会报一个错误,可见当静态库和动态库同时存在的时候,程序会优先使用动态库。
(二)实例1使用库
详细过程可参照hello程序过程
1.代码
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 *);
#endiftest.c
#include<stdio.h>
#include"A.h"
int main()
{
print1(1);
print2("test");
exit(0);
}操作步骤:

2. 程序中使用静态库
ar crv libfile.a A1.o A2.o
gcc -o test test.c libfile.a


错误解决方式:将test.c中的exit(0)修改为return 0
3. 动态库的使用
gcc -shared -fPIC -o A1.o A2.o
gcc -o test test.c

(三)实例2使用库
详细过程可参照hello程序过程
代码
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);
#endifmain.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 -c sub1.c sub2.c

静态库
ar crv libsub.a sub1.o sub2.o
gcc -o main main.c libsub.a

动态库
gcc -shared -fPIC sub1.o sub2.o
gcc -o main main.c

静态库与动态库的生成文件的比较
静态库

动态库

通过比较发现静态库要比动态库要小很多,生成的可执行文件大小也存在较小的差别。
二、ubantu16.04安装opencv-3.4.1
(一)OpenCV简介
OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。 它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
OpenCV用C++语言编写,它具有C ++,Python,Java和MATLAB接口,并支持Windows,Linux,Android和Mac OS,OpenCV主要倾向于实时视觉应用,并在可用时利用MMX和SSE指令, 如今也提供对于C#、Ch、Ruby,GO的支持。
(二)OpenCV下载
1 官网下载Sources版本(下载很慢,重复下载很多次才成功,需要耐心)
国内快速下载地址:https://www.bzblog.online/wordpress/index.php/2020/03/09/opencvdownload/
2 将下载文件复制到home目录下,进行解压配置:

进入命令行模式:
- 解压包
unzip opencv-3.4.1.zip- 进入到解压后的文件包中
cd opencv-3.4.1- 安装依赖库和cmake ,如果提醒需要apt-get update,那就先sudo su进入root权限,再sudo apt-get
update,然后在执行下面命令
sudo apt-get install cmakesudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg.dev libtiff5.dev libswscale-dev libjasper-dev- 安装完cmake之后执行命令 ,创建编译文件夹
mkdir my_build_dir进入文件夹进行配置
cd my_build_dir
- cmake一下
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..- 执行命令,漫长的编译过程
sudo make
下载完成:

- 执行命令
sudo make install- sudo make install 执行完毕后OpenCV编译过程就结束了,接下来就需要配置一些OpenCV的编译环境首先将OpenCV的库添加到路径,从而可以让系统找到
sudo gedit /etc/ld.so.conf.d/opencv.conf执行此命令后打开的可能是一个空白的文件,不用管,只需要在文件末尾添加
/usr/local/lib- 保存回到命令行界面
- 执行如下命令使得刚才的配置路径生效
sudo ldconfig- 配置bash
sudo gedit /etc/bash.bashrc在最末尾添加
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH
- 保存,执行如下命令使得配置生效
source /etc/bash.bashrc更新
sudo updatedb至此所有的配置都已经完成
(三)opencv的实例
3 Linux下编程:
- 在opencv-3.4.1下新建文件夹mytest
cd opencv-3.4.1mkdir mytest创建test.cpp
touch test.cpp进入编程
sudo gedit /test.cpp
#sudo vim /test.cpp
#根据自己配置编辑器进行编辑编辑下面代码: 注意补全头文件<opencv2.hightgui.cpp><opencv2/opencv.hpp>;
其中图片路径直接放在home目录下;
源码:
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
CvPoint center;
double scale = -3;
IplImage* image = cvLoadImage("lena.jpg");
argc == 2? cvLoadImage(argv[1]) : 0;
cvShowImage("Image", image);
if (!image) return -1; center = cvPoint(image->width / 2, image->height / 2);
for (int i = 0;i<image->height;i++)
for (int j = 0;j<image->width;j++) {
double dx = (double)(j - center.x) / center.x;
double dy = (double)(i - center.y) / center.y;
double weight = exp((dx*dx + dy*dy)*scale);
uchar* ptr = &CV_IMAGE_ELEM(image, uchar, i, j * 3);
ptr[0] = cvRound(ptr[0] * weight);
ptr[1] = cvRound(ptr[1] * weight);
ptr[2] = cvRound(ptr[2] * weight);
}
Mat src;Mat dst;
src = cvarrToMat(image);
cv::imwrite("test.png", src);
cvNamedWindow("test",1); imshow("test", src);
cvWaitKey();
return 0;
}- 保存并编译:
gcc test.cpp -o test `pkg-config --cflags --libs opencv`
gcc编译器:gcc +文件名+ -o+输出文件流名称 +` 支持包
- 运行
./test





















