生成静态库和动态库文件
在桌面上建立目录,导航到目录,在建立三个文件,hello.c main.c hello.h mkdir a ,cd a, touch hello.c main.c hello.h 分别编辑程序
#include<stdio.h>
void hello(const char *name)
{
printf("Hello %s!\n",name);
}
#include <stdio.h>
#include "hello.h"
int main()
{
hello("everyone");
return 0;
}
#ifndef _HELLO_H_
#define _HELLO_H_
#include<stdio.h>
void hello(const char *name);
#endif
建立hello.o文件
shu@shu-virtual-machine:~$ cd ~/桌面/a
shu@shu-virtual-machine:~/桌面/a$ touch hello.c
shu@shu-virtual-machine:~/桌面/a$ gedit hello.c
shu@shu-virtual-machine:~/桌面/a$ gcc -c hello.c
shu@shu-virtual-machine:~/桌面/a$ ls
hello.c hello.h hello.o main.c
有了hello.o目标文件,之后可以创建静态库。 用ar -crv libmyhello.a hello.o 函数创建静态库,静态库函数前缀为lib,后缀为.a中间文件名,后面为目标文件。
shu@shu-virtual-machine:~/桌面/a$ ar -crv libmyhello.a hello.o
a - hello.o
shu@shu-virtual-machine:~/桌面/a$ ls
hello.c hello.h hello.o libmyhello.a main.c
shu@shu-virtual-machine:~/桌面/a$
在程序中使用静态库,先生成main.o目标文件
shu@shu-virtual-machine:~/桌面/a$ gcc -c main.c
shu@shu-virtual-machine:~/桌面/a$ ls
hello.c hello.h hello.o libmyhello.a main.c main.o
shu@shu-virtual-machine:~/桌面/a$
后面建立可执行文件
shu@shu-virtual-machine:~/桌面/a$ gcc -o 1 main.o libmyhello.a
shu@shu-virtual-machine:~/桌面/a$ ls
1 hello.c hello.h hello.o libmyhello.a main.c main.o
运行文件
shu@shu-virtual-machine:~/桌面/a$ ./1
Hello everyone!
删除静态库文件在执行文件
shu@shu-virtual-machine:~/桌面/a$ rm -rf libmyhello.a
shu@shu-virtual-machine:~/桌面/a$ ls
1 hello.c hello.h hello.o main.c main.o
shu@shu-virtual-machine:~/桌面/a$ ./1
Hello everyone!
下面进行动态库的使用 首先通过目标文件建立动态库文件前缀为lib,文件名,后缀为.so gcc命令为gcc -shared -fPIC -o libmyhello.so hello.o
root@shu-virtual-machine:~/桌面/a# gcc -shared -fPIC -o libmyhello.so hello.o
root@shu-virtual-machine:~/桌面/a# ls
1 2 hello.c hello.h hello.o libmyhello.a libmyhello.so main.c main.o
接下来就是使用动态库,将libmyhello.so移动到/usr/lib
sudo cp libmyhello.so /usr/lib
生成可执行文件,并执行
root@shu-virtual-machine:~/桌面/a# gcc main.c libmyhello.so -o 2
root@shu-virtual-machine:~/桌面/a# ls
1 2 hello.c hello.h hello.o libmyhello.a libmyhello.so main.c main.o
root@shu-virtual-machine:~/桌面/a# ./2
Hello everyone!
root@shu-virtual-
总结:在动态库和静态库同名时系统会优先使用动态库除非强调静态库,在选择动态库的时候,我们要将自己定义的动态库放入目录/usr/lib下面
gcc -o 2 main.c -L. lmyhello
静态库和动态库文件的使用
在目录d下面创建相关程序文本文件
shu@shu-virtual-machine:~/桌面$ cd d
shu@shu-virtual-machine:~/桌面/d$ touch 1.c 2.c 3.h 4.c
shu@shu-virtual-machine:~/桌面/d$ ls
1.c 2.c 3.h 4.c
#include<stdio.h>
void print1(int arg)
{
printf("1 print arg:%d\n",arg);
}
#include<stdio.h>
void print2(char *arg)
{
printf("2 print arg:%s\n",arg);
}
#ifndef _3_H_
#define _3_H_
#include<stdio.h>
void print1(int);
void print2(char *);
#endif
#include<stdio.h>
#include"3.h"
int main()
{
print1(1);
print2("test");
return 0;
}
生成目标文件后在生成静态库
shu@shu-virtual-machine:~/桌面/d$ gcc -c 1.c 2.c
shu@shu-virtual-machine:~/桌面/d$ ls
1.c 1.o 2.c 2.o 3.h 4.c
shu@shu-virtual-machine:~/桌面/d$ ar -crv liball.a 1.o 2.o
a - 1.o
a - 2.o
shu@shu-virtual-machine:~/桌面/d$ ls
1.c 1.o 2.c 2.o 3.h 4.c liball.a
执行静态库文件和主程序
shu@shu-virtual-machine:~/桌面/d$ gcc -o all 4.c -L. -lall
shu@shu-virtual-machine:~/桌面/d$ ls
1.c 1.o 2.c 2.o 3.h 4.c all liball.a
shu@shu-virtual-machine:~/桌面/d$ ./all
1 print arg:1
2 print arg:test
生成动态库文件
shu@shu-virtual-machine:~/桌面/d$ gcc -c -fPIC 1.c 2.c
shu@shu-virtual-machine:~/桌面/d$ ls
1.c 1.o 2.c 2.o 3.h 4.c all liball.a
shu@shu-virtual-machine:~/桌面/d$ gcc -shared -fPIC -o liball.so 1.o 2.o
shu@shu-virtual-machine:~/桌面/d$ ls
1.c 1.o 2.c 2.o 3.h 4.c all liball.a liball.so
连接动态库并执行主程序
shu@shu-virtual-machine:~/桌面/d$ gcc -o all1 4.c liball.so
shu@shu-virtual-machine:~/桌面/d$ ls
1.c 1.o 2.c 2.o 3.h 4.c all all1 liball.a liball.so
shu@shu-virtual-machine:~/桌面/d$ sudo cp liball.so /usr/lib
[sudo] shu 的密码:
shu@shu-virtual-machine:~/桌面/d$ ls
1.c 1.o 2.c 2.o 3.h 4.c all all1 liball.a liball.so
shu@shu-virtual-machine:~/桌面/d$ ./all1
1 print arg:1
2 print arg:test
编写程序并生成动态库和静态库,运行程序
创建下列函数文本文件
#include<stdio.h>
#include"1.h"
int main()
{
int x=4,y=2;
float t=x2x(x,y);
float s=x2y(x,y);
printf("%f\n",t);
printf("%f\n",s);
}
#include<stdio.h>
float x2x(int x,int y)
{float n=(float)x/y;
return n;
}
#include<stdio.h>
float x2y(int a,int b)
{
float z=a+b;
return z;
}
#ifndef _1_H_
#define _1_H_
#include<stdio.h>
float x2x(int x,int y);
float x2y(int x,int y);
#endif
生成目标文件后生成静态库并执行文件
shu@shu-virtual-machine:~/桌面/c$ gcc -c x2x.c x2y.c
shu@shu-virtual-machine:~/桌面/c$ ls
1.h main.c x2x.c x2x.o x2y.c x2y.o
shu@shu-virtual-machine:~/桌面/c$ ar -crv liball.a x2x.o x2y.o
a - x2x.o
a - x2y.o
shu@shu-virtual-machine:~/桌面/c$ ls
1.h liball.a main.c x2x.c x2x.o x2y.c x2y.o
shu@shu-virtual-machine:~/桌面/c$ gcc -o all main.c -L. -lall
shu@shu-virtual-machine:~/桌面/c$ ls
1.h all liball.a main.c x2x.c x2x.o x2y.c x2y.o
shu@shu-virtual-machine:~/桌面/c$ ./all
2.000000
6.000000
生成动态库并执行
shu@shu-virtual-machine:~/桌面/c$ gcc -c -fPIC x2x.c x2y.c
shu@shu-virtual-machine:~/桌面/c$ gcc -shared -fPIC -o liball.so x2x.o x2y.o
shu@shu-virtual-machine:~/桌面/c$ ls
1.h all liball.a liball.so main.c x2x.c x2x.o x2y.c x2y.o
shu@shu-virtual-machine:~/桌面/c$ sudo cp liball.so /usr/lib
shu@shu-virtual-machine:~/桌面/c$ ls
1.h all liball.a liball.so main.c x2x.c x2x.o x2y.c x2y.o
shu@shu-virtual-machine:~/桌面/c$ gcc main.c liball.so -o all1
shu@shu-virtual-machine:~/桌面/c$ ls
1.h all all1 liball.a liball.so main.c x2x.c x2x.o x2y.c x2y.o
shu@shu-virtual-machine:~/桌面/c$ ./all1
2.000000
6.000000
linux gcc下常用命令
创建文本文件并理解编译过程
shu@shu-virtual-machine:~$ cd ~/桌面/e
shu@shu-virtual-machine:~/桌面/e$ touch main.c
shu@shu-virtual-machine:~/桌面/e$ gedit main.c
shu@shu-virtual-machine:~/桌面/e$ gcc -E main.c -o main.i
shu@shu-virtual-machine:~/桌面/e$ ls
main.c main.i
对main.c进行预处理 接下来对main.c进行汇编
shu@shu-virtual-machine:~/桌面/e$ gcc -s main.i -o main.s
shu@shu-virtual-machine:~/桌面/e$ ls
main.c main.i main.s
之后可以对其进行汇编文件,生成目标文件
shu@shu-virtual-machine:~/桌面/e$ gcc -c main.c
shu@shu-virtual-machine:~/桌面/e$ ls
main.c main.i main.o main.s
shu@shu-virtual-machine:~/桌面/e$
最后对目标文件进行封装连接
shu@shu-virtual-machine:~/桌面/e$ gcc main.o -o main
shu@shu-virtual-machine:~/桌面/e$ ls
main main.c main.i main.o main.s
编译目标文件,其实是在系统目录下找到include库函数
shu@shu-virtual-machine:~/桌面/e$ gcc -c -I /usr/dev/mysql/include main.c -o 1
shu@shu-virtual-machine:~/桌面/e$ ls
1 main main.c main.i main.o main.s
在目录下找到相关文件连接到可执行文件
shu@shu-virtual-machine:~/桌面/e$ gcc main.o -o 2
shu@shu-virtual-machine:~/桌面/e$ ./2
hello world
分析gcc编译后的相关文件
shu@shu-virtual-machine:~/桌面/e$ gcc main.c -o main
shu@shu-virtual-machine:~/桌面/e$ size main
text data bss dec hex filename
1182 552 8 1742 6ce main
动态库连接,用size来查看大小
hu@shu-virtual-machine:~/桌面/e$ ldd main
linux-vdso.so.1 => (0x00007ffe1f276000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f30bb206000)
/lib64/ld-linux-x86-64.so.2 (0x00007f30bb5d0000)
静态库连接
shu@shu-virtual-machine:~/桌面/e$ gcc -static main.c -o main1
shu@shu-virtual-machine:~/桌面/e$ size main1
text data bss dec hex filename
824102 7284 6360 837746 cc872 main1
shu@shu-virtual-machine:~/桌面/e$ ldd main1
不是动态可执行文件
分析生成的文件格式
shu@shu-virtual-machine:~/桌面/e$ readelf -S main
共有 31 个节头,从偏移量 0x19d8 开始:
节头:
[号] 名称 类型 地址 偏移量
大小 全体大小 旗标 链接 信息 对齐
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000400238 00000238
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.ABI-tag NOTE 0000000000400254 00000254
0000000000000020 0000000000000000 A 0 0 4
[ 3] .note.gnu.build-i NOTE 0000000000400274 00000274
0000000000000024 0000000000000000 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0000000000400298 00000298
000000000000001c 0000000000000000 A 5 0 8
[ 5] .dynsym DYNSYM 00000000004002b8 000002b8
0000000000000060 0000000000000018 A 6 1 8
[ 6] .dynstr STRTAB 0000000000400318 00000318
000000000000003d 0000000000000000 A 0 0 1
[ 7] .gnu.version VERSYM 0000000000400356 00000356
0000000000000008 0000000000000002 A 5 0 2
[ 8] .gnu.version_r VERNEED 0000000000400360 00000360
0000000000000020 0000000000000000 A 6 1 8
[ 9] .rela.dyn RELA 0000000000400380 00000380
0000000000000018 0000000000000018 A 5 0 8
[10] .rela.plt RELA 0000000000400398 00000398
0000000000000030 0000000000000018 AI 5 24 8
[11] .init PROGBITS 00000000004003c8 000003c8
000000000000001a 0000000000000000 AX 0 0 4
[12] .plt PROGBITS 00000000004003f0 000003f0
0000000000000030 0000000000000010 AX 0 0 16
[13] .plt.got PROGBITS 0000000000400420 00000420
0000000000000008 0000000000000000 AX 0 0 8
[14] .text PROGBITS 0000000000400430 00000430
0000000000000182 0000000000000000 AX 0 0 16
[15] .fini PROGBITS 00000000004005b4 000005b4
0000000000000009 0000000000000000 AX 0 0 4
[16] .rodata PROGBITS 00000000004005c0 000005c0
0000000000000010 0000000000000000 A 0 0 4
[17] .eh_frame_hdr PROGBITS 00000000004005d0 000005d0
0000000000000034 0000000000000000 A 0 0 4
[18] .eh_frame PROGBITS 0000000000400608 00000608
00000000000000f4 0000000000000000 A 0 0 8
[19] .init_array INIT_ARRAY 0000000000600e10 00000e10
0000000000000008 0000000000000000 WA 0 0 8
[20] .fini_array FINI_ARRAY 0000000000600e18 00000e18
0000000000000008 00000000
反汇编ELF,使用相关指令将其反汇编
shu@shu-virtual-machine:~/桌面/e$ objdump -D main
main: 文件格式 elf64-x86-64
Disassembly of section .interp:
0000000000400238 <.interp>:
400238: 2f (bad)
400239: 6c insb (%dx),%es:(%rdi)
40023a: 69 62 36 34 2f 6c 64 imul $0x646c2f34,0x36(%rdx),%esp
400241: 2d 6c 69 6e 75 sub $0x756e696c,%eax
400246: 78 2d js 400275 <_init-0x153>
400248: 78 38 js 400282 <_init-0x146>
40024a: 36 2d 36 34 2e 73 ss sub $0x732e3436,%eax
400250: 6f outsl %ds:(%rsi),(%dx)
400251: 2e 32 00 xor %cs:(%rax),%al
Disassembly of section .note.ABI-tag:
0000000000400254 <.note.ABI-tag>:
400254: 04 00 add $0x0,%al
400256: 00 00 add %al,(%rax)
400258: 10 00 adc %al,(%rax)
40025a: 00 00 add %al,(%rax)
40025c: 01 00 add %eax,(%rax)
40025e: 00 00 add %al,(%rax)
400260: 47 rex.RXB
400261: 4e 55 rex.WRX push %rbp
400263: 00 00 add %al,(%rax)
400265: 00 00 add %al,(%rax)
400267: 00 02 add %al,(%rdx)
400269: 00 00 add %al,(%rax)
40026b: 00 06 add %al,(%rsi)
40026d: 00 00 add %al,(%rax)
40026f: 00 20 add %ah,(%rax)
400271: 00 00 add %al,(%rax)
...
opencv下的 图像处理技术
安装opencv之后进行下列操作 opencv安装博客上有很多教程 创建目录创建文本文件代码如下 在编译代码时要在同一个目录下要保存一张图片为lena.jpg格式
shu@shu-virtual-machine:~/桌面$ mkdir e
shu@shu-virtual-machine:~/桌面$ cd e
shu@shu-virtual-machine:~/桌面/e$ touch code
shu@shu-virtual-machine:~/桌面/e$ gedit code.cpp
shu@shu-virtual-machine:~/桌面/e$ g++ code.cpp -o test1 `pkg-config --cflags --libs opencv`
shu@shu-virtual-machine:~/桌面/e$ ls
code code.cpp test1
shu@shu-virtual-machine:~/桌面/e$ ./test1
shu@shu-virtual-machine:~/桌面/e$ ls
code code.cpp lena.jpg test1 test.png
#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;
}
运行结果 原图 运行图 opencv下面,进行视频播放 先进行代码编译和创建 test.cpp
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
VideoCapture capture("man.mp4");
while(1){
Mat frame;
capture >> frame;
if(frame.empty())
break;
imshow("读取视频帧",frame);
waitKey(30);
}
system("pause");
return 0;
}
在这个目录下要保存一 man.mp4视频
shu@shu-virtual-machine:~/桌面/e$ touch test2.cpp
shu@shu-virtual-machine:~/桌面/e$ gedit test2.cpp
shu@shu-virtual-machine:~/桌面/e$ g++ test2.cpp -o test2 `pkg-config --cflags --libs opencv`
shu@shu-virtual-machine:~/桌面/e$
shu@shu-virtual-machine:~/桌面/e$ ls
code code.cpp lena.jpg man.mp4 test1 test2 test2.cpp test.png
shu@shu-virtual-machine:~/桌面/e$ ./test2
sh: 1: pause: not found
运行结果 opencv下进行录制视频 创建test3.cpp,完成相关编程
#include<iostream>
#include <opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int main()
{
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << "error" << endl;
waitKey(0);
return 0;
}
int w = static_cast<int>(cap.get(CV_CAP_PROP_FRAME_WIDTH));
int h = static_cast<int>(cap.get(CV_CAP_PROP_FRAME_HEIGHT));
Size videoSize(w, h);
VideoWriter writer("RecordVideo.avi", CV_FOURCC('M', 'J', 'P', 'G'), 25, videoSize);
Mat frame;
int key;
char startOrStop = 1;
char flag = 0;
while (1)
{
cap >> frame;
key = waitKey(100);
if (key == 32)
{
startOrStop = 1 - startOrStop;
if (startOrStop == 0)
{
flag = 1;
}
}
if (key == 27)
{
break;
}
if (startOrStop == 0 && flag==1)
{
writer << frame;
cout << "recording" << endl;
}
else if (startOrStop == 1)
{
flag = 0;
cout << "end recording" << endl;
}
imshow("picture", frame);
}
cap.release();
writer.release();
destroyAllWindows();
return 0;
}
shu@shu-virtual-machine:~/桌面/e$ g++ test3.cpp -o test3 `pkg-config --cflags --libs opencv`
shu@shu-virtual-machine:~/桌面/e$ ls
code code.cpp lena.jpg man.mp4 test1 test2 test2.cpp test3 test3.cpp test.png
shu@shu-virtual-machine:~/桌面/e$ ./test3
end recording
end recording
end recording
end recording
end recording
end recording
end recording
end recording
end recording
end recording
end recording
end recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
shu@shu-virtual-machine:~/桌面/e$ ls
code code.cpp lena.jpg man.mp4 RecordVideo.avi test1 test2 test2.cpp test3 test3.cpp test.png
录制成功后生成.avi文件
|