在VSCode中用C构建Linux数学函数SO库及编译执行方案
一、修正后的代码文件
1. math_functions.h(添加头文件保护,规范函数声明)
#ifndef MATH_FUNCTIONS_H #define MATH_FUNCTIONS_H #include <math.h> // 自定义平方根(处理负数输入) double custom_sqrt(double num); // 自定义向上取整 double custom_ceil(double num); // 自定义向下取整 double custom_floor(double num); // 自定义幂运算(处理0的负次幂异常) double custom_power(double base, double exp); #endif // MATH_FUNCTIONS_H
2. math_functions.c(实现函数逻辑,增加异常处理)
#include "math_functions.h" #include <stdio.h> double custom_sqrt(double num) { if (num < 0) { fprintf(stderr, "[ERROR] custom_sqrt: 输入不能为负数\n"); return NAN; } return sqrt(num); } double custom_ceil(double num) { return ceil(num); } double custom_floor(double num) { return floor(num); } double custom_power(double base, double exp) { if (base == 0 && exp < 0) { fprintf(stderr, "[ERROR] custom_power: 0不能取负指数\n"); return NAN; } return pow(base, exp); }
3. main.c(测试用例,规范函数调用)
#include "math_functions.h" #include <stdio.h> int main() { // 测试平方根 printf("custom_sqrt(16) = %.2f\n", custom_sqrt(16)); printf("custom_sqrt(-4) = %.2f\n", custom_sqrt(-4)); // 测试向上取整 printf("custom_ceil(3.2) = %.2f\n", custom_ceil(3.2)); printf("custom_ceil(-2.7) = %.2f\n", custom_ceil(-2.7)); // 测试向下取整 printf("custom_floor(5.8) = %.2f\n", custom_floor(5.8)); printf("custom_floor(-1.3) = %.2f\n", custom_floor(-1.3)); // 测试幂运算 printf("custom_power(2, 3) = %.2f\n", custom_power(2, 3)); printf("custom_power(0, -2) = %.2f\n", custom_power(0, -2)); return 0; }
二、手动编译步骤
1. 直接编译为可执行程序(快速测试)
执行以下命令:
# 编译生成目标文件 gcc -c math_functions.c -o math_functions.o -Wall gcc -c main.c -o main.o -Wall # 链接生成可执行文件(-lm 必须加,用于链接系统数学库) gcc math_functions.o main.o -o math_test -lm
运行程序:
./math_test
2. 创建动态共享库(.so)并编译测试程序
第一步:生成动态库
# 生成位置无关代码的目标文件 gcc -fPIC -c math_functions.c -o math_functions.o -Wall # 生成动态库 gcc -shared -o libmathfuncs.so math_functions.o -lm
第二步:编译链接动态库的测试程序
gcc main.c -o math_test_so -L. -lmathfuncs -Wall
第三步:运行程序(指定动态库路径)
LD_LIBRARY_PATH=. ./math_test_so
若想永久生效,可将
libmathfuncs.so复制到/usr/lib或/usr/local/lib目录
三、Makefile 编写(自动化编译)
创建名为Makefile的文件,内容如下:
# 编译器与编译选项 CC = gcc CFLAGS = -Wall -fPIC LDFLAGS = -lm # 目标文件与产物 OBJ = math_functions.o main.o TARGET = math_test SO_LIB = libmathfuncs.so SO_TARGET = math_test_so # 默认目标:编译普通可执行程序 all: $(TARGET) # 编译普通可执行程序 $(TARGET): $(OBJ) $(CC) $(OBJ) -o $@ $(LDFLAGS) # 编译动态库及对应测试程序 so: $(SO_LIB) $(SO_TARGET) $(SO_LIB): math_functions.o $(CC) -shared -o $@ $^ $(LDFLAGS) $(SO_TARGET): main.c $(CC) $< -o $@ -L. -lmathfuncs $(CFLAGS) # 编译单个目标文件 %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ # 清理编译产物 clean: rm -f $(OBJ) $(TARGET) $(SO_LIB) $(SO_TARGET)
Makefile 使用说明
- 执行
make:默认生成普通可执行程序math_test - 执行
make so:生成动态库libmathfuncs.so和链接动态库的测试程序math_test_so - 执行
make clean:删除所有编译生成的文件
四、常见错误排查
- 编译时出现
undefined reference to sqrt:忘记加-lm链接系统数学库 - 头文件重复定义:未添加
#ifndef头文件保护 - 动态库编译报错
relocation R_X86_64_32:未加-fPIC生成位置无关代码 - 运行动态库程序提示找不到库:未用
LD_LIBRARY_PATH指定库路径,或未将库放入系统目录
内容的提问来源于stack exchange,提问作者Anomy
相关产品推荐
相关产品推荐

