做C语言开发的都知道,在Linux环境中动态链接库以 .so结尾;在Windows环境中动态链接库以 .dll结尾。在讲使用之前,我先来给大家补补基础。

链接库分为 静态链接库动态链接库。

静态链接库(a库):在 编译 的时候,库函数中函数的定义已经编译到源文件中,所以,静态链接库在编译完之后存不存在无关紧要。

动态链接库(so库):在 编译 的时候,库函数中函数的定义没有编译到源文件中,只是指定了库文件的路径,所以,编译之后源文件的执行还是依赖于so库文件。

静态链接库和动态链接库的区别在于,主程序在运行前,静态链接库的链接固定写入在程序中,而动态链接库则是在每次程序运行再加载链接。

如果对C语言编译 四步走 不熟悉的同学可以参考这篇文章 :微观的C/C++编译执行过程

在实际开发过程中,动态链接库用的居多,所以,我下面仅讲其的使用步骤:

代码示例

准备一个 .c 库函数文件

#include<stdio.h>
#include<stdlib.h>

int wust_test(int value){
    printf("%d\n",value);
}

在这里我建议大家也写一个 .h 文件,也就是你这个库函数里面包含 函数的一个申明,这样函数的含义 和 用法便一目了然了。如下:

//功能:测试 so 动态链接库
//参数一:整型 
int wust_test(int value);

将这个库函数编译成 so 动态链接库

gcc test.c  -fPIC -shared -o libtest.so

gcc 依赖库文件 -fPIC -shared -o libxxx.so

libxxx.so 必须以 lib 开头 .so结尾

-fPIC       作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),
  则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意
  位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。

-shared     目的是使源码编译成动态库 .so 文件

这个时候 so动态链接库 就生成了,下面我们来看看调用

编写 main.c 文件

#include<stdio.h>
#include<stdlib.h>

int wust_test(int value);

int main(){
    wust_test(33);
    return 0;
}

编译 main.c 文件

gcc main.c -o main -L. -ltest

-L 指定依赖库文件所在的目录

-l 指定依赖库 libtest.so --> -ltest

执行 main

./main

这个时候你会发现报错:大概意思就是找不到库文件。解决方法如下:

将 so动态链接库文件路径赋值给环境变量 LD_LIBRARY_PATH

export LD_LIBRARY_PATH=$(pwd): 

LD_LIBRARY_PATH:环境变量
pwd:当前目录的路径
::分隔符

再运行就可以了 

SO文件调用原理回顾

       大家看到这里就可以发现,动态链接库的创建和使用其实并不难。下面我将为大家梳理一下其中的思路。

       我们在编写 main.c 的时候可以看到,和普通的 main.c 没太大区别,关键点在于 wust_test() 这个方法没实现;那这怎么办呢?动态链接库就起作用了。我们将 动态链接库文件所在路径 配置给 环境变量 LD_LIBRARY_PATH,所以,当系统在找 wust_test() 方法的实现的时候,就会找到这个库,所以请注意:你不配置是找不到滴。在编译的时候,我们也用到了动态链接库,-L指定库文件路径,-l指定库文件,你不指定也会报错。

GitHub 加速计划 / li / linux-dash
13
2
下载
A beautiful web dashboard for Linux
最近提交(Master分支:4 个月前 )
186a802e added ecosystem file for PM2 5 年前
5def40a3 Add host customization support for the NodeJS version 5 年前
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐