Head First C 笔记 - 静态库与动态库

静态库与动态库

共享.h头文件

有三种方式

  • 放入标准目录,比如/usr/local/include,系统.h头文件位于/usr/include
  • 使用绝对路径
  • gcc -I(大写i)指定头文件 gcc -I/my_header_file_path ...

共享.o目标文件(静态库)

跟共享.h头文件一样,.o文件同样也可以使用完整路径来共享。

如果目标文件太多,可以使用ar命令创建目标文件.a存档文件

ar -rcs libsafe.a checksum.o encrypt.o

r表示存在则更新,c表示忽略反馈信息,s表示创建索引,注意名称必须是lib***.a的格式,编译时使用-l指定库名。然后将.a文件保存在库目录中,通常是/usr/local/lib,或者其他目录,如果是其他目录,编译时需要使用-L指定路径,比如:

gcc test_code.c -L/my_lib -lsafe -o test_code

可以使用nm命令查看存档中的内容:

nr libsafe.a

动态库

静态库的缺陷是编译时链接,每次修改都需要重新构建整个程序。动态库则不一样,它是在运行时动态链接。可以看成是加强版的目标文件。

假设有如下文件目录,这是一个跑步机的显示器demo程序,main.c会调用hfcal.c或者hfcal_UK.c中的函数,显示用户的运动情况。hfcal.c和hfcal_UK.c是不同地区的驱动代码,区别是展现的单位不一样。

├── hfcal.c
├── hfcal_UK.c
├── include
│ └── hfcal.h
├── libs
└── main.c

main.c

#include <stdio.h>
#include <hfcal.h>
int main()
{
    display_calories(115.1, 11.2, 0.9);
    return 0;
}

hfcal.h

void display_calories(float weight, float distance, float coeff);

hfcal.c

#include <stdio.h>
#include <hfcal.h>
void display_calories(float weight, float distance, float coeff)
{
    printf("weight: %3.2f lbs\n", weight);
    printf("distance: %3.2f miles\n", distance);
    printf("calories burned: %4.2f cal\n", coeff);
}

hfcal_UK.c

#include <stdio.h>
#include <hfcal.h>

void display_calories(float weight, float distance, float coeff)
{
    printf("weight: %3.2f kg\n", weight / 2.2046);
    printf("distance: %3.2f km\n", distance * 1.609344);
    printf("calories burned: %4.2f cal\n", coeff * weight * distance);
}

首先创建hfcal.c的动态链接库:

gcc -Iinclude -fPIC -c hfcal.c -o hfcal.o // 创建目标文件
gcc -shared hfcal.o -o ./libs/libhfcal.so // 创建动态链接库
gcc main.c -Iinclude -Llibs -lhfcal -o main // 使用
./main

第一步创建目标文件,其实就比之前多了一个-fPIC参数,它告诉编译器创建跟未知无关的代码。第二步使用-shared参数将.o文件转化为动态链接库。最后使用其实跟使用静态库一样,同样使用-l参数指定库名。

现在的目录结构为:

├── hfcal.c
├── hfcal.o
├── hfcal_UK.c
├── include
│ └── hfcal.h
├── libs
│ └── libhfcal.so
├── main
└── main.c

最后还可以测试一下,将hfcal_UK.c编译为动态库,替换之前的库。

gcc -Iinclude -fPIC -c hfcal_UK.c -o hfcal_UK.o
mv libs/libhfcal.so libs/libhfcal.so.bak // 备份
gcc -shared hfcal_UK.o -o ./libs/libhfcal.so
./main

这样main不用重新编译,就能使用新的代码了,因为它实在运行时动态链接的。

PS:gcc常用命令导航

  • -c预编译
  • -I 指定头文件 (include) 目录
  • -L 指定库目录
  • -l 指定库
  • -o 重命名生成文件
  • -fPIC 创建与位置无关代码
  • -shared 生成动态链接库

标签: c

添加新评论