库的生成和使用:静态库、动态库
这篇博客写完后,总想加入这段话:写博客的目的是我了自己知识的积累,但是也尽量帮助其他人学习理解,所以写博客时尽量想让博客通俗易懂,有一个逻辑的过程,但是写完后,发现做到通篇博客顺着一个逻辑的过程很难,因为嵌入式不像数理化有很多需要推导的过程,它的难学就在于散的规则太多,这些规则知道就知道不知道就不知道,只能是知道的越多写的越顺手而已。我想起了一段话:一流的人才制定规则,二流的人才用好规则,三流的人才远离规则,我们还没法制定规则,只能尽量利用好规则。
1. 静态库的生成和使用
定义一个 hello.c
#include <stdio.h>
void hello(void)
{
printf("helloworld!\n");
}
定义一个 hello.h
#ifndef _HELLO_H
#define _HELLO_H
void hello(void);
#endif
使用gcc hello.c -c -o hello.o 命令生成目标文件hello.o
使用 ar rcs libhello.a hello.o 命令生成静态库文件libhello.a (注意库文件的格式前缀lib后缀.a)
定义一个main.c文件调用静态库
#include <stdio.h>
#include "hello.h"
int main(int argc, const char *argv[])
{
hello();
return0;
}
使用gcc main.c -L./ -lhello -o main生成可执行文件
注:-L加库文件的路径./代表当前路径,-l加库文件的库名,libhello.a的库名为hello
如果定义Makefile编译静态库程序,Makefile如下:
.PHONY:clean
OBJ = main
OBJ1 = main.o
OBJ2 = hello
CC = gcc
CFLAGS = -c -o
$(OBJ): $(OBJ1) lib$(OBJ2).a
$(CC)$< -L./ -l$(OBJ2) -o $(OBJ)
%.o:%.c
$(CC)$< $(CFLAGS) $@
lib$(OBJ2).a:$(OBJ2).o
arrcs lib$(OBJ2).a $(OBJ2).o
clean:
rm-f $(OBJ) $(OBJ1) $(OBJ2).o lib$(OBJ2).a
1. 动态库的生成和使用
定义hello.c与hello.h内容如上,
使用gcc hello.c -fPIC -c -o hello.o生成hello.o
使用gcc -o libhello.so -shared hello.o生成libhello.so
定义main.c如上
使用gcc main.c -fPIC -c -o main.o生成main.o
使用gcc main.o -L./ -lhello -o main生成可执行文件main
执行./main,出错原因如下:
./main: error while loading sharedlibraries: libhello.so: cannot open shared object file: No such file ordirectory
报错原因找不到libhello.so,为什么静态库没报错而动态库报错,因为静态库在编译时已经加载进可执行文件中了,而动态库在编译时没有加载进可执行文件,动态库是在执行时才加载的,可执行文件在执行时需要在常用的动态库路径下去找libhello.so发现没找到,所以报错。
解决方法:将libhello.so拷贝到常用的动态库路径下
sudo cp libhello.so /usr/lib
再去执行./main就可以了
hello world!
如果定义Makefile编译静态库程序,Makefile如下:
.PHONY:clean
OBJ = main
OBJ1 = main.o
OBJ2 = hello
CC = gcc
CFLAGS = -c -o
$(OBJ): $(OBJ1) lib$(OBJ2).so
$(CC)$< -L./ -l$(OBJ2) -o $(OBJ)
%.o:%.c
$(CC)$< -fPIC $(CFLAGS) $@
lib$(OBJ2).so:$(OBJ2).o
$(CC)-o lib$(OBJ2).so -shared $(OBJ2).o
clean:
rm-f $(OBJ) $(OBJ1) $(OBJ2).o lib$(OBJ2).so
执行./main
hello world!