Linux 可执行程序动态库搜索路径/Linux 程序加载找不到动态库

遇到一个问题,linux下可执行程序启动时,找不到同目录下动态库。原来,linux下默认不加载当前目录下动态库,可通过如下配置加载当前目录下的动态库。

一、如何让linux加载当前目录的动态库

linux的excutable在执行的时候缺省是先搜索/lib和/usr/lib这两个目录,然后按照ld.so.conf里面的配置搜索绝对路径,linux缺省是不会在当前目录搜索动态库的。

windows加载动态库的时候,缺省是首先加载本地目录下的动态库,然后再搜索windows/system和windows/system32目录。

windows的动态库搜索顺序,虽然有可能会造成潜在的混乱,但是对于开发和测试无疑是比较方便的,尤其是debug和release版本的动态库需要经常切换进行测试的时候。linux的动态库搜索顺序虽然可以说成是比较严谨,但是相对来说也比较呆板,有时候会造成不便。

其实,linux也可以支持“加载当前目录的动态库”。只要设置合适的环境变量LD_LIBRARY_PATH就可以了。设置方法有以下三种:

1、临时修改,log out之后就失效

在terminal中执行:export LD_LIBRARY_PATH=./
或者:
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

2、让当前帐号以后都优先加载当前目录的动态库

修改~/.bash_profile在文件末尾加上两行: LD_LIBRARY_PATH=./ 和 export LD_LIBRARY_PATH


# 2020年 5月 13日 星期三 14:20:48 CST
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/data1/mayue6/usr/lib/"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/data1/mayue6/usr/local/gmp-6.2.0/lib/"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/data1/mayue6/usr/local/mpfr-4.0.2/lib/"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/data1/mayue6/usr/local/mpc-1.1.0/lib/"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/data1/mayue6/usr/local/gcc-4.9.3/lib64/"
# 

在这里插入图片描述
在这里插入图片描述

3、让所有帐号从此都优先加载当前目录的动态库

修改/etc/profile 在文件末尾加上两行:

LD_LIBRARY_PATH=./export LD_LIBRARY_PATH 

PS:修改ld.so.conf不能达到我们的目的,因为ld.so.conf只支持绝对路径。

二、Linux下程序运行时动态库查找路径和优先级顺序

按优先级顺序如下:

  1. 通过在编译目标代码时指定该程序的动态库搜索路径(用 -wl,rpath 或-R选项而不是-L)
  2. 通过环境变量LD_LIBRARY_PATH指定的动态库搜索路径
  3. 通过配置文件 /etc/ld.so.conf 中指定的动态库搜索路径(只支持绝对路径
  4. Linux 动态库的默认搜索路径是 /lib 和 /usr/lib (优先级先/lib再/usr/lib)(应该是系统指定的)

2.1 编译时通过- Wl,-rpath 指定

编译目标代码时指定的动态库搜索路径(指的是用 -wl,rpath-R选项而不是-L),readelf -d命令可以查看编译的目标文件中rpath参数;

示例

#编译
gcc test.c -Wl,-rpath=/mayuelib

#查看
readelf -d a.out

在这里插入图片描述

2.2 运行前通过LD_LIBRARY_PATH 指定

  • 可以在系统的/etc/profile中添加
  • 可以在用户的profile文件中添加
  • 可以在被调用的启动脚本中添加
  • 可以手动添加(仅对当前终端有效、其他SSH/串口终端无效)

添加环境变量后设定生效示例:source ~/.bashrc

#会覆盖原值
export LD_LIBRARY_PATH=/root/test/env/lib

#在原来基础上增加路径
export LD_LIBRARY_PATH=/app/lib:$LD_LIBRARY_PATH

2.3 运行前通过 /etc/ld.so.conf 指定

将动态库路径追加到/etc/ld.so.conf文件或者/etc/ld.so.conf.d/目录下的文件后,记得一定要执行ldconfig 命令,该命令会将配置的所有路径下的库载入缓存文件/etc/ld.so.cache中。(系统重启后也要执行一次 ldconfig 可以添加到开启自启动脚本中)

示例

root@imx6qdlsabresd:/app/test# cat /etc/ld.so.conf
/tmp/app

示例2
在这里插入图片描述
在这里插入图片描述

2.4 优先级顺序图示

在这里插入图片描述

三、参考资料

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在C#编程中,动态库是一个非常重要的概念,它可以让我们复用代码,提高程序的效率和可维护性。但是,在使用动态库时,我们需要知道它的路径顺序,才能正确地引入和使用它。本文将结合实例,介绍C#搜索动态库路径顺序。 一、什么是动态库? 在C#编程中,动态库是指一种可以被程序动态加载文件。它包含了一些可以被程序调用的函数、变量和类等。动态库的优点在于可以被多个程序复用,可以减少代码的重复编写,提高程序的效率和可维护性。 常见的动态库格式包括: 1. DLL(Dynamic Link Library):Windows平台上常用的动态库格式。 2. SO(Shared Object):Linux平台上常用的动态库格式。 3. DYLIB(Dynamic Library):MacOS平台上常用的动态库格式。 二、动态库路径顺序 在使用动态库时,我们需要知道它的路径顺序,才能正确地引入和使用它。一般来说,C#会按照以下顺序搜索动态库: 1. 程序所在的目录 2. 环境变量PATH中指定的目录 3. 系统默认的目录 程序所在的目录是指运行程序的可执行文件所在的目录。一般情况下,我们可以将动态库放在程序所在的目录下,以便程序可以直接加载它。 环境变量PATH中指定的目录是指在系统环境变量中设置的目录,C#会按照环境变量PATH中的顺序搜索动态库。如果我们需要在程序中使用某个动态库,但是它不在程序所在的目录下,可以将它放在环境变量PATH中指定的目录下,或者将它的路径添加到环境变量PATH中。 系统默认的目录是指操作系统默认的目录,C#会按照操作系统的规定搜索动态库。例如,在Windows操作系统中,C#会搜索Windows系统目录和Windows系统目录下的子目录,以及注册表中指定的路径。 三、实例演示 下面,我们将演示如何使用C#搜索动态库路径顺序。 1. 在程序所在的目录下创建一个动态库mylib.dll,包含一个函数Add和一个类MyClass。 ``` // mylib.dll using System; namespace MyLib { public class MyClass { public int Value { get; set; } public MyClass(int value) { Value = value; } public int Add(int a, int b) { return a + b; } } } ``` 2. 在程序中使用mylib.dll中的函数和类。 ``` // Program.cs using System; using MyLib; namespace SearchDLL { class Program { static void Main(string[] args) { // 到mylib.dll的路径 string dllPath = FindDLL("mylib.dll"); // 加载mylib.dll Assembly assembly = Assembly.LoadFrom(dllPath); // 使用mylib.dll中的函数和类 MyClass myClass = new MyClass(10); Console.WriteLine(myClass.Add(1, 2)); Console.ReadLine(); } // 查找动态库路径 static string FindDLL(string dllName) { // 程序所在的目录 string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, dllName); if (File.Exists(path)) { return path; } // 环境变量PATH中指定的目录 string[] dirs = Environment.GetEnvironmentVariable("PATH").Split(';'); foreach (string dir in dirs) { path = Path.Combine(dir, dllName); if (File.Exists(path)) { return path; } } // 系统默认的目录 path = Path.Combine(Environment.SystemDirectory, dllName); if (File.Exists(path)) { return path; } throw new FileNotFoundException($"不到动态库{dllName}!"); } } } ``` 在上面的代码中,我们首先定义一个名为mylib.dll的动态库,包含一个类MyClass和一个函数Add。然后,在程序中调用FindDLL函数查找动态库mylib.dll的路径。FindDLL函数会按照C#搜索动态库路径顺序搜索动态库动态库后,使用Assembly.LoadFrom函数加载动态库,并使用其中的函数和类。 四、总结 本文介绍了C#搜索动态库路径顺序,并结合实例演示了如何使用C#搜索动态库路径顺序。在使用动态库时,我们需要注意动态库路径顺序,以便程序可以正确地引入和使用动态库
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值