在软件开发中,动态库(Dynamic Library)和静态库(Static Library)是两种常见的代码组织和链接方式。它们在项目开发和维护中扮演着重要的角色,为了更好地理解它们,让我们深入研究这两种库的使用方法和链接过程。
静态库:libxxx.a
静态库是在编译时被链接到可执行文件中的库。通常以.a为后缀。当使用静态库时,需要在编译时指定头文件的路径和链接库的路径,以下是一些解决方法:
1.使用 -I 选项指定头文件路径:
gcc xxx.c -I ./lib/xxxx/
但这样在链接时可能会报错找不到库。
2.使用 -L 选项指定库文件路径:
gcc xxx.c -I ./lib/xxx/ -L ./lib/xxxxx/
但仍然可能找不到库,因为当前路径下可能有多个.a文件。
3.使用 -l 选项指定库,并去掉前缀和后缀:
gcc xxx.c -I ./lib/xxx/ -L ./lib/xxxxx/ -lxxx
紧跟 -l 后面
演示(创建一个静态库并使用):
//mymath.h
1 #pragma once
2
3 #include <stdio.h>
4
5
6 int Add(int a , int b);
7 int Sub(int a , int b);
//mymath.c
1 #include "mymath.h"
2
3 int Add(int a, int b)
4 {
5 return a+b;
6 }
7
8 int Sub(int a ,int b)
9 {
10 return a-b;
11 }
//makefile
1 static-lib=libmymath.a
2
3 $(static-lib):mymath.o
4 ar -rc $@ $^
5
6 mymath.o:mymath.c
7 gcc -c $^
8
9 .PHONY:clean
10 clean:
11 rm -rf *.o *.a
12
13 .PHONY:output
14 output:
15 mkdir -p mylib/include
16 mkdir -p mylib/lib
17 cp *.h mylib/include
18 cp *.a mylib/lib
//main.c
1 #include "mymath.h"
2
3 int main()
4 {
5 printf("3+3=%d\n",Add(3,3));
6
7 return 0;
8 }
动态库:libYYY.so
动态库在运行时被加载到内存中。通常以.so为后缀。以下是一些使用动态库的方法:
1.编译产生位置无关码:
gcc -fPIC -c xxx.c
使用 -fPIC 产生位置无关码,直接使用偏移量进行库中函数的编址
2.链接生成动态库
gcc -shared -o libmyfile.so *.o
3.使用 -I、-L 和 -l 选项指定库和路径:
gcc -I lib/include/ -L lib/mylib -lmyfile
如果使用多个库且在同一目录下,只需要 -l 加上去掉前后缀的名称。如果在不同目录下,仍然需要 -I 和 -L 选项,加上路径和文件名。
//mylog.h
1 #pragma once
2
3 #include<stdio.h>
4
5 void Print();
//mylog.c
1 #include"mylog.h"
2
3 void Print()
4 {
5 printf("hello dynamic depot\n");
6 printf("hello dynamic depot\n");
7 printf("hello dynamic depot\n");
8 printf("hello dynamic depot\n");
9 printf("hello dynamic depot\n");
10 printf("hello dynamic depot\n");
11 }
//Makefile
1 static-lib=libmymath.a
2 dy-lib=libmylog.so
3
4 .PHONY:all
5 all:$(static-lib) $(dy-lib)
6
7 $(static-lib):mymath.o
8 ar -rc $@ $^
9
10 mymath.o:mymath.c
11 gcc -c $^
12
13 $(dy-lib):mylog.o
14 gcc -shared -o $@ $^
15
16 mylog.o:mylog.c
17 gcc -fPIC -c $^
18
19 .PHONY:clean
20 clean:
21 rm -rf *.o *.a
22
23 .PHONY:output
24 output:
25 mkdir -p mylib/include
26 mkdir -p mylib/lib
27 cp *.h mylib/include
28 cp *.a mylib/lib
29 cp *.so mylib/lib
解决动态库执行时找不到文件的问题
在执行时,动态库可能找不到文件。解决方法包括:
1.将文件拷贝到系统默认的库路径,如 /lib64/ 或 /usr/lib64/ 下。
2.在系统默认的库路径下建立软链接。
ln -s /your/library/path/libmyfile.so /usr/lib64/
3.使用环境变量 LD_LIBRARY_PATH 指定库的路径。
export LD_LIBRARY_PATH=/your/library/path:$LD_LIBRARY_PATH
注意,这种方式在关闭终端后会失效。
4.在 /etc/ld.so.conf.d/ 路径下创建一个文件,将动态库文件路径放到文件中,然后运行 ldconfig 重新加载。
echo "/your/library/path" > /etc/ld.so.conf.d/mylib.conf
ldconfig
这样设置是永久有效的。
通过深入了解动静态库的使用和解决路径问题,我们可以更好地优化代码结构和提高软件的可维护性。