Linux库概念及相关编程
分文件编程案例
分文件编程是指将程序按功能模块划分成不同的文件进行编写,这种方法有以下好处:
- 功能责任划分:每个文件对应一个功能模块,职责明确,易于理解和维护。
- 方便调试:可以单独编译和测试每个模块,定位和修复问题更加方便。
- 主程序简洁:主程序只负责调用各个模块的接口,代码简洁明了。
例如,一个涉及网络、超声波和电机控制的项目,可以分别创建三个模块:
- 网络模块 (
network.c
) - 超声波模块 (
ultrasonic.c
) - 电机模块 (
motor.c
)
这些模块的头文件如下:
network.h
ultrasonic.h
motor.h
静态库和动态库
静态库
静态库在编译时直接被加入到目标程序中。优点是运行速度快,发布时无需提供库文件,但缺点是生成的可执行文件较大。
制作静态库
- 编译源文件生成目标文件(
.o
文件):gcc -c calcufuncs.c -o calcufuncs.o
- 创建静态库文件(
.a
文件):ar rcs libcalcufunc.a calcufuncs.o
使用静态库
- 编译时指定库文件路径和库名:
gcc calculatorT.c -lcalcufunc -L ./ -o mainProStatic
动态库
动态库在程序运行时被加载。优点是节省内存和磁盘空间,缺点是运行速度稍慢。
制作动态库
- 编译源文件生成动态库(
.so
文件):gcc -shared -fPIC calcufuncs.c -o libcalc.so
使用动态库
- 编译时指定库文件路径和库名:
gcc calculatorT.c -lcalc -L ./ -o mainProDy
- 运行时指定动态库路径:
export LD_LIBRARY_PATH="/home/pi/back/test" ./mainProDy
示例代码
network.c
#include "network.h"
#include <stdio.h>
void init_network()
{
printf("Network initialized.\n");
}
network.h
#ifndef NETWORK_H
#define NETWORK_H
void init_network();
#endif
#include "ultrasonic.h"
#include <stdio.h>
void init_ultrasonic()
{
printf("Ultrasonic sensor initialized.\n");
}
ultrasonic.h
#ifndef ULTRASONIC_H
#define ULTRASONIC_H
void init_ultrasonic();
#endif
motor.c
#include "motor.h"
#include <stdio.h>
void init_motor()
{
printf("Motor initialized.\n");
}
motor.h
#ifndef MOTOR_H
#define MOTOR_H
void init_motor();
#endif
main.c
#include "network.h"
#include "ultrasonic.h"
#include "motor.h"
int main() { init_network();
init_ultrasonic(); init_motor();
return 0;
Makefile
# Variables CC = gcc CFLAGS = -Wall -fPIC LDFLAGS = -shared
# Source files SRC = network.c ultrasonic.c motor.c
OBJ = $(SRC:.c=.o) STATIC_LIB = libmylib.a DYNAMIC_LIB = libmylib.so
# Targets .PHONY: all static dynamic clean all: static dynamic static: $(OBJ) ar rcs
$(STATIC_LIB) $(OBJ) dynamic: $(SRC) $(CC) $(CFLAGS) $(LDFLAGS) -o $(DYNAMIC_LIB) $(SRC)
clean: rm -f $(OBJ) $(STATIC_LIB) $(DYNAMIC_LIB)
参考文献
- Linux中的库
- CSDN博客 - Linux 内库