You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 04:12:54