C语言如何自定义链接库——编译与调用

目录

  • 前言
  • 一、基础文件准备(核心代码)
  • [二、方式 1:直接编译(简易版,无独立库)](#二、方式 1:直接编译(简易版,无独立库))
  • [三、方式 2:编译为静态库(.a)【推荐分发使用】](#三、方式 2:编译为静态库(.a)【推荐分发使用】)
  • [四、方式 3:编译为动态库(.so)【大型项目首选】](#四、方式 3:编译为动态库(.so)【大型项目首选】)

前言

在 C 语言开发中,将通用功能封装为独立库是提升代码复用性、项目可维护性的核心手段。本文以自定义简易 math 库为例 ,手把手教你实现直接编译、静态库(.a)、动态库(.so) 三种编译调用方式

一、基础文件准备(核心代码)

我们先创建 3 个核心文件,实现add(加法)、sub(减法)两个基础数学函数,结构清晰、可直接复用。

  1. math.h(头文件:函数声明):头文件用于声明函数接口,添加头文件保护宏防止重复包含,这是 C 语言开发的标准规范。
c 复制代码
#ifndef MATH_H
#define MATH_H

// 加法函数声明
int add(int a, int b);
// 减法函数声明
int sub(int a, int b);

#endif
  1. math.c(源文件:函数实现):实现头文件中声明的函数逻辑,是库文件的核心代码。
c 复制代码
#include "math.h"

// 加法实现
int add(int a, int b) {
    return a + b;
}

// 减法实现
int sub(int a, int b) {
    return a - b;
}
  1. main.c(主程序:调用库函数):主程序文件,引入自定义头文件,调用 math 库中的函数完成测试。
c 复制代码
#include <stdio.h>
#include "math.h"  // 引入自定义math库头文件

int main() {
    int a = 10, b = 5;
    // 调用库函数
    printf("%d + %d = %d\n", a, b, add(a, b));
    printf("%d - %d = %d\n", a, b, sub(a, b));
    return 0;
}

二、方式 1:直接编译(简易版,无独立库)

适合小型项目 / 临时测试,不生成独立库文件,直接将所有源文件编译为可执行程序,简单快捷。

  1. 编译:将main.c和math.c一起编译,生成可执行文件main

    gcc main.c math.c -o main

  2. 运行程序

    ./main

运行结果

三、方式 2:编译为静态库(.a)【推荐分发使用】

静态库是编译时嵌入可执行文件的库文件(后缀.a),运行时无外部依赖,适合独立分发工具。

完整步骤

  1. 编译生成目标文件(.o):仅编译不链接,生成中间目标文件

    gcc -c math.c -o math.o

参数说明:-c 表示只执行编译操作,不进行链接。

  1. 打包生成静态库(libmath.a):使用ar命令将目标文件打包为静态库,Linux 库文件必须以lib开头。

    ar rcs libmath.a math.o

参数说明:

r:替换 / 插入文件到库中;

c:创建新库;

s:生成库索引,提升链接速度。

  1. 编译主程序,链接静态库

    gcc main.c -L. -lmath -o main

参数说明:

-L.:指定库文件搜索路径为当前目录;

-lmath:链接名为libmath.a的静态库(自动补全lib前缀和.a后缀)。

  1. 运行程序

四、方式 3:编译为动态库(.so)【大型项目首选】

动态库(共享库,后缀.so)是运行时加载的库,多个程序可共享使用,节省内存,适合大型项目、系统级开发。

  1. 编译生成动态库(libmath.so

    gcc -shared -fPIC math.c -o libmath.so

参数说明:

-shared:指定生成动态共享库;

-fPIC:生成位置无关代码(动态库必备参数)。

  1. 编译主程序,链接动态库:命令与静态库完全一致,编译器会优先匹配.so动态库:

    gcc main.c -L. -lmath -o main

  2. 关键:解决动态库运行依赖------直接运行./main会报错:error while loading shared libraries: libmath.so

原因: 系统默认仅搜索/lib//usr/lib等系统目录,不会查找当前目录。
解决方案: 将当前路径加入库文件路径中。

复制代码
export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH
  1. 运行

    ./main

相关推荐
希望永不加班2 小时前
SpringBoot 配置绑定:@ConfigurationProperties
java·spring boot·后端·spring
悟空码字2 小时前
MySQL性能优化的天花板:10条你必须掌握的顶级SQL分析技巧
java·后端·mysql
indexsunny2 小时前
互联网大厂Java面试实战:Spring Boot、MyBatis与Kafka在电商场景中的应用
java·spring boot·面试·kafka·mybatis·电商·技术栈
殷紫川2 小时前
CompletableFuture 异步编程全解:核心能力、编排方案、异常处理与超时控制
java
ss2732 小时前
致Java初学者的一封信
java·开发语言
white-persist2 小时前
【vulhub spring CVE-2018-1270】CVE-2018-1270 Spring Messaging 远程命令执行漏洞 完整复现详细分析解释
java·服务器·网络·数据库·后端·python·spring
JaneHan_2 小时前
STM32CubeMX+HAL+Keil5 PWM呼吸灯
c语言·stm32·单片机
潇洒畅想2 小时前
1.1 从∑到∫:用循环理解求和与累积
java·数据结构·python·算法
维齐洛波奇特利(male)3 小时前
@Pointcut(“execution(* com.hdzx..*(..))“)切入点与aop 导致无限循环
java·开发语言