如何在C语言中创建和使用静态和动态库

The purpose

在Linux上,可以创建两种类型的库,即静态库(.a)和动态库(.so),但在编译时需要使用相似的方法。也就是说,即使存在不同库的libA.a和libA.so,编译命令中省略了库的扩展名,如gcc xxx -lA,因此无法确定使用哪一个库。

我想要验证当libA.a和libA.so共存时的行为,并做些记录。

先提出结论

如果在命令中指定了库libA(使用-lA选项),则动态库libA.so将优先于静态库libA.a进行链接。

在中文中,原文的释义是:在追加说明中,通过指定“-static”的选项,可以链接静态库libA.a。

追加说明:
通过gcc -o main main.c -L. -static -lA这样的编译命令,可以链接静态库libA.a。

在编译命令中使用gcc的”-Wl”选项,通过指定”-Bdynamic”(动态)或”-Bstatic”(静态),可以选择库文件。非常感谢yumetodo先生的建议!

样本代码

使用下面这段代码。
此外,将num设置为5时使用静态库,将num设置为10时使用动态库,可以确定在编译时使用了哪一个。

在C语言中声明全局变量。

创建和验证动态库

#include<stdio.h>
#include"A.h"

 void A(){
     num = 10;   //動的ライブラリでnumを10にする
     printf("inside A, num = %d\n", num);
 }
#Aの共有(動的)ライブラリを作成
[pirlo@centos8 02]$ gcc -shared -o libA.so -c A.c
・・・
#メイン処理をコンパイルして実行ファイルを作成
[pirlo@centos8 02]$ gcc -o main main.c -L. -lA -lB
#ファイル一覧
[pirlo@centos8 02]$ ls
A.c  A.h  B.c  B.h  libA.so  libB.so  main  main.c
[pirlo@centos8 02]$ ./main 
inside A, num = 10
inside B, num = 10

创建并验证静态库。

#include<stdio.h>
#include"A.h"

 void A(){
     num = 5;   //静的ライブラリのここだけは違う
     printf("inside A, num = %d\n", num);
 }
#Aの静的ライブラリを作成
[pirlo@centos8 02]$ gcc -c A.c B.c   #オブジェクト「.o」ファイルが作成される
[pirlo@centos8 02]$ ls
A.c  A.h  A.o  B.c  B.h  B.o  main.c
[pirlo@centos8 02]$ ar rcs libA.a A.o   #オブジェクトファイルから静的ライブラリを作成
[pirlo@centos8 02]$ ls
A.c  A.h  A.o  B.c  B.h  B.o  libA.a  main.c
・・・Bの関連処理を略・・・
#メイン処理をコンパイルして実行ファイルを作成(コマンドは動的の時と完全一致)
[pirlo@centos8 02]$ gcc -o main main.c -L. -lA -lB
#ファイル一覧
[pirlo@centos8 02]$ ls
A.c  A.h  A.o  B.c  B.h  B.o  libA.a  libB.a  main  main.c
[pirlo@centos8 02]$ ./main 
inside A, num = 5
inside B, num = 5

在存在动态和静态库共存的情况下,请再次确认。

#ファイル一覧
[pirlo@centos8 02]$ ls
A.c  A.h  A.o  B.c  B.h  B.o  libA.a  libA.so  libB.a  libB.so  main.c
#同じコンパイルコマンドで実行ファイルを再作成
[pirlo@centos8 02]$ gcc -o main main.c -L. -lA -lB
[pirlo@centos8 02]$ ./main 
inside A, num = 10
inside B, num = 10

总结

如果动态和静态库同时存在,优先引用动态库。

如果添加”-static”选项,则会引用静态库。

[pirlo@centos8 02]$ ls
A.c  A.h  A.o  B.c  B.h  B.o  libA.a  libA.so  libB.a  libB.so  main.c
#「-static」オプション無し
[pirlo@centos8 02]$ gcc -o main main.c -L. -lA -lB
[pirlo@centos8 02]$ ./main 
inside A, num = 10
inside B, num = 10
#「-static」オプション有り
[pirlo@centos8 02]$ gcc -o main main.c -L. -static -lA -lB
[pirlo@centos8 02]$ ./main 
inside A, num = 5
inside B, num = 5

使用gcc的”-Wl”选项,可以通过指定”-Bdynamic”(动态)或”-Bstatic”(静态)来选择库。

#AとBの静的ライブラリを使用
[pirlo@centos8 02]$ gcc -o main main.c -L. -static-libgcc -Wl,-Bdynamic,-lc,-Bstatic,-lA,-lB
[pirlo@centos8 02]$ ./main 
inside A, num = 5
inside B, num = 5
#すべての動的ライブラリを使用
[pirlo@centos8 02]$ gcc -o main main.c -L. -static-libgcc -Wl,-Bdynamic,-lc,-lA -lB
[pirlo@centos8 02]$ ./main 
inside A, num = 10
inside B, num = 10

各个参考对象

请参考下面的内容创建一个动态库。

17.3 在GCC中创建动态库。

请参考以下内容来创建一个静态库。

17.4. 使用GCC和ar创建静态库。

广告
将在 10 秒后关闭
bannerAds