精华内容
下载资源
问答
  • Windows/Linux链接器加载动态库的搜索路径顺序

    Windows/Linux链接器加载动态库的搜索路径顺序


    如需转载请标明出处:http://blog.csdn.net/itas109
    QQ技术交流群:129518033

    目录

    系统:Ubuntu 16.04.5 64bit
    系统:windows 7 64bit


    前言

    Windows/Linux程序运行时,其动态库的路径搜索是有顺序的。本文介绍其搜索顺序。

    1.Windows链接器加载动态库的搜索路径顺序

    通过隐式和显式链接,Windows首先搜索“已知DLL”,例如Kernel32.dll和User32.dll。 Windows然后按以下顺序搜索DLL:

    1. 当前进程的可执行模块所在的目录
    2. 当前目录
    3. Windows系统目录。如C:\Windows\System32,GetSystemDirectory函数检索此目录的路径
    4. Windows目录。 如C:\Windows,GetWindowsDirectory函数检索此目录的路径
    5. PATH环境变量中列出的目录

    英文原文:

    Windows then searches for the DLLs in the following sequence:
    1. The directory where the executable module for the current process is located.
    2. The current directory.
    3. The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.
    4. The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.
    5. The directories listed in the PATH environment variable.
    

    2.Linux链接器加载动态库的搜索路径顺序

    链接器使用以下搜索路径来查找所需的共享库:

    1. -rpath-link选项指定的任何目录。

    2. -rpath选项指定的任何目录。-rpath和-rpath-link之间的区别在于-rpath选项指定的目录包含在可执行文件中并在运行时使用,而-rpath-link选项仅在链接时有效。

    gcc main.c -rpath dir_path
    
    1. 在ELF系统上,对于本机链接器,如果是-rpath和-rpath-link选项未使用,搜索环境变量“LD_RUN_PATH”的内容。 在SunOS上,如果未使用-rpath选项,搜索指定的任何目录使用-L选项。

    2. 对于本机链接器,搜索环境变量的内容“LD_LIBRARY_PATH”。

    3. 对于本机ELF链接器,共享的“DT_RUNPATH”或“DT_RPATH”中的目录在库中搜索它所需的共享库。 “DT_RPATH”条目是如果存在“DT_RUNPATH”条目,则忽略。

    4. 默认目录,通常是/lib和/usr/lib。

    5. 对于ELF系统上的本机链接器,如果文件/etc/ld.so.conf存在,则列表在该文件中找到的目录。

    如果找不到所需的共享库,链接器将发出警告并且继续链接。

    英文原文:

    ld - The GNU linker
    
    -rpath-link=dir
               When using ELF or SunOS, one shared library may require another.  This happens when an
               "ld -shared" link includes a shared library as one of the input files.
    
               When the linker encounters such a dependency when doing a non-shared, non-relocatable
               link, it will automatically try to locate the required shared library and include it
               in the link, if it is not included explicitly.  In such a case, the -rpath-link option
               specifies the first set of directories to search.  The -rpath-link option may specify
               a sequence of directory names either by specifying a list of names separated by
               colons, or by appearing multiple times.
    
               This option should be used with caution as it overrides the search path that may have
               been hard compiled into a shared library. In such a case it is possible to use
               unintentionally a different search path than the runtime linker would do.
    
               The linker uses the following search paths to locate required shared libraries:
    
               1.  Any directories specified by -rpath-link options.
    
               2.  Any directories specified by -rpath options.  The difference between -rpath and
                   -rpath-link is that directories specified by -rpath options are included in the
                   executable and used at runtime, whereas the -rpath-link option is only effective
                   at link time. Searching -rpath in this way is only supported by native linkers and
                   cross linkers which have been configured with the --with-sysroot option.
    
               3.  On an ELF system, for native linkers, if the -rpath and -rpath-link options were
                   not used, search the contents of the environment variable "LD_RUN_PATH".
    
               4.  On SunOS, if the -rpath option was not used, search any directories specified
                   using -L options.
    
               5.  For a native linker, search the contents of the environment variable
                   "LD_LIBRARY_PATH".
    
               6.  For a native ELF linker, the directories in "DT_RUNPATH" or "DT_RPATH" of a shared
                   library are searched for shared libraries needed by it. The "DT_RPATH" entries are
                   ignored if "DT_RUNPATH" entries exist.
    
               7.  The default directories, normally /lib and /usr/lib.
    
               8.  For a native linker on an ELF system, if the file /etc/ld.so.conf exists, the list
                   of directories found in that file.
    
               If the required shared library is not found, the linker will issue a warning and
               continue with the link.
    

    Refrence:

    1. Search Path Used by Windows to Locate a DLL
    2. ld on ubuntu
    3. Using ld The GNU linker

    觉得文章对你有帮助,可以扫描二维码捐赠给博主,谢谢!
    在这里插入图片描述
    如需转载请标明出处:http://blog.csdn.net/itas109
    QQ技术交流群:129518033

    展开全文
  • Linux加载库目录顺序

    千次阅读 2017-04-23 13:20:12
    linux的excutable在执行的时候缺省是...windows加载动态库的时候,缺省是首先加载本地目录下的动态库,然后再搜索windows/system和windows/system32目录windows动态库搜索顺序,虽然有可能会造成潜在的混乱,但是


    linux的excutable在执行的时候缺省是先搜索/lib和/usr/lib这两个目录,然后按照ld.so.conf里面的配置搜索绝对路径,linux缺省是不会在当前目录搜索动态库的。windows加载动态库的时候,缺省是首先加载本地目录下的动态库,然后再搜索windows/system和windows/system32目录。
    windows的动态库搜索顺序,虽然有可能会造成潜在的混乱,但是对于开发和测试无疑是比较方便的,尤其是debug和release版本的动态库需要经常切换进行测试的时候。linux的动态库搜索顺序虽然可以说成是比较严谨,但是相对来说也比较呆板,有时候会造成不便。


    ldd LB //查看进程依赖的动态库

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

    1、临时修改,log out之后就失效
    在terminal中执行:export LD_LIBRARY_PATH=./

    2、让当前帐号以后都优先加载当前目录的动态库
    修改~/.bash_profile在文件末尾加上两行: LD_LIBRARY_PATH=./ 和 export LD_LIBRARY_PATH 

    3、让所有帐号从此都优先加载当前目录的动态库
    修改/etc/profile在文件末尾加上两行: LD_LIBRARY_PATH=./ 和 export LD_LIBRARY_PATH 

    PS:修改ld.so.conf不能达到我们的目的,因为ld.so.conf只支持绝对路径。
    展开全文
  • windows与linux动态库搜索顺序

    千次阅读 2013-04-27 15:21:38
    1、在配置文件/etc/ld.so.conf中指定动态库搜索路径(需要添加其它库文件的路径,在文件的最后添加具体的路径即可 [ 如:/usr/local/lib ],添加后保存退出,然后在命令行ldconfig 2、通过环境变量LD_LIB

    打开动态库函数(dlopen或LoadLibrary)中指定动态库的文件名,在程序运行时按照以下次序来搜索动态库


    一、库文件的搜索路径:

    1、在配置文件/etc/ld.so.conf中指定动态库搜索路径(需要添加其它库文件的路径,在文件的最后添加具体的路径即可 [ 如:/usr/local/lib ],添加后保存退出,然后在命令行ldconfig

    2、通过环境变量LD_LIBRARY_PATH指定动态库搜索路径(当通过该环境变量指定多个动态库搜索路径时,路径之间用冒号":"分隔)

    3、在编译目标代码时指定该程序的动态库搜索路径(还可以在编译目标代码时指定程序的动态库搜索路径。 这是通过gcc 的参数"-Wl,-rpath,"指定,当指定多个动态库搜索路径时,路径之间用冒号":"分隔)

    4、默认的动态库搜索路径/lib

    5、默认的动态库搜索路径/usr/lib

    使用GCC编译,则有:gcc -o test test.c -L../ -lmylib -Wl,-rpath,/home/wangl/testWork

    其中,

    -L../表明在链接时,从../目录寻找需要链接的动态库;

    -lmylib 表明要链接的库名为libmylib.so;

    -Wl,-rpath,/home/wangl/testWork表明在执行时,从/home/wangl/testWork目录寻找要加载的动态库。

    注:-Wl,-rpath可以指定绝对路径,也可以指定相对路径。

    如果指定相对路径,则程序在执行时,会以程序的当前目录为基础来计算相对路径。

    可以使用ldd命令查看当前程序依赖的动态库的路径。


    Linux下搜索路径的次序:

    1)  ELF可执行文件中动态段中DT_RPATH所指定的路径,不常用但是比较使用的方法;

    2)  编译目标代码时指定的动态库搜索路径(-WI,-rpath=./);

    3)  环境变量LD_LIBRARY_PATH指定的动态库搜索路径;(LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径)

    4)  配置文件/etc/ld.so.conf(或ld.so.cache)中指定的动态库搜索路径;

    5)  默认的动态库搜索路径/lib;

    6)  默认的动态库搜索路径/usr/lib。



    在上述1-3中指定的动态库搜索路径都可以指定多个搜索目录,其先后顺序是按指定路径的先后顺序搜索的。如果动态库之间存在依赖关系,那么先加载那些被依赖的动态库。

     在windows下,程序执行时,会在当前目录下寻找相应的dll库。如果在当前目录下找不到,就会到系统目录system和system32中去找。

    Windows下搜索路径次序

    1)  可执行文件所在的目录(当前目录);

    2)  Windows的系统目录(该目录可以通过GetSystemDirectory函数获得);

    3)  16位的系统目录(Windows目录下的system子目录);

    4)  Windows目录(该目录可以通过GetWindowsDirectory函数获得);

    5)  进程当前所在的工作目录;

    6)  PATH环境变量中所列出的目录。

    注:工作目录位于Windows目录之后,这一改变开始于Windows XP SP2之后
    展开全文
  •   国内一般操作系统为windows操作系统,但是mac系统在高端市场,也占据着一部分比率,开发Mac应用,需要先了解,Mac操作系统搜索动态库顺序。 1.搜索顺序   因为运行时动态库的搜索路径的先后顺序是:    ...

      国内一般操作系统为windows操作系统,但是mac系统在高端市场,也占据着一部分比率,开发Mac应用,需要先了解,Mac操作系统搜索动态库的顺序。

    1.搜索顺序

      因为运行时动态库的搜索路径的先后顺序是:
        a.编译目标代码时指定的动态库搜索路径;
        b.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
        c.配置文件/etc/ld.so.conf中指定的动态库搜索路径;
        d.默认的动态库搜索路径/lib和/usr/lib;
        /lib和/usr/lib只有root权限才可以修改,配置文件/etc/ld.so.conf也需要root权限。

    2.和应用程序一同发布

      在xcode下编译出的程序,在开发机器上运行是没有问题的。但是给其他用户用,就可能出问题。因为用户不一定有这个库。有两种方法可以解决这个问题;一是给其他用户也安装依赖的库文件;二是将所有的dylib随行发布,消除依赖。 第一种方案不考虑,大部分时候这样做并不现实;下面说说如何随行发布dylib。单纯将依赖的dylib文件拷贝到可执行文件目录下一同传输过去是不能消除依赖的;执行的时候还是报错;在编译一个动态库的时候, 你需要指定 INSTALL_PATH. 也就是它的安装路径;编译完成后如果一个可执行程序使用了该动态库, 那么在编译可执行程序的时候, 动态库的 INSTALL_PATH 会被记录到可执行程序中, 用来定位这个动态库。因此我们首先需要将用到的dylib文件都拷贝到可执行文件目录下,然后改变动态库的INSTALL_PATH;将其改到可执行文件所在目录;需要注意的是:如果依赖多个动态库,用到的动态库已会依赖其他动态库,因此用到的所有的动态库的依赖动态库路径都需要修改。
      以OpenCV为例子,假设最终编译出来的可执行文件为 macimgproc;执行命令:otool -L macimgproc可看到如下的输出:

    macimgproc:
        /usr/local/opt/opencv/lib/libopencv_calib3d.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_contrib.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_core.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_features2d.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_flann.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_gpu.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_highgui.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_imgproc.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_legacy.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_ml.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_nonfree.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_objdetect.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_ocl.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_photo.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_stitching.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_superres.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_video.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_videostab.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 307.4.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)
    

      说明macimgproc依赖所有的OpenCV动态库文件;因此首先需要将所有动态库文件拷贝到macimgproc所在目录,然后需要将macimgproc文件中的所有/usr/local/opt/opencv/lib/libopencv_xxx修改为@executable_path/libopencv_xxx;@executable_path表示可执行文件所在目录;指示所有OpenCV动态库从可执行文件所在目录查找;更多@executable_path的介绍以及其他变量参见文章 @rpath, @loader_path, @executable_path。使用命令install_name_tool -change {old.dylib} {new.dylib} {filename}修改动态库的INSTALL_PATH,例如:

    install_name_tool -change /usr/local/Cellar/opencv/2.4.12/lib/libopencv_flann.2.4.dylib @executable_path/libopencv_flann.2.4.dylib macimgproc
    

      执行后重新otool -L macimgproc可看到如下的输出:

    macimgproc:
        ...
        /usr/local/opt/opencv/lib/libopencv_features2d.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        @executable_path/libopencv_flann.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        /usr/local/opt/opencv/lib/libopencv_gpu.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
        ...
    

      整个OpenCV库大概有19个dylib文件,因此写了一个简单的批量修改脚本

    #!/usr/bin/ruby
    
    Preview=0
    
    def fix_opencv_lib_link(file,rlib)
        if(rlib.include?('libopencv'))
            name = rlib.split('/').last
            cmd = "install_name_tool -change #{rlib} @executable_path/#{name} #{file}"
            if Preview == 1
                puts "Preivew: #{cmd}"
            else
                `#{cmd}`
            end
        else 
            puts "ignore rlib: #{rlib}";
        end
    end
    
    def fix_file_rely_lib(file)
      puts "===============start change #{file}==============="
      linklibs = `otool -L #{file}`.split("\n")
      linklibs.delete_at(0)
      linklibs.each_with_index do |rlib,i|
        rlib = rlib.split()[0]
        fix_opencv_lib_link(file,rlib)
      end
    end
    
    def doopencvlist
      # puts "Preview: #{Preview}"
      `ls |grep libopencv`.split().each_with_index do |file,i|
        fix_file_rely_lib(file)
      end
    end
    
    def viewlib(file)
        puts `otool -L #{file}`
    end
    
    if __FILE__ == $0
      if ARGV[0] == 'preview'
        Preview = 1;
        doopencvlist();
      elsif ARGV[0] == 'view'
        `ls |grep libopencv`.split().each_with_index do |file,i|
          # puts "===============start view #{file}==============="
          viewlib(file)
        end
      elsif ARGV[0] == 'do'
        doopencvlist();
      elsif ARGV[0] == 'previewfile'
        Preview = 1;
        fix_file_rely_lib(ARGV[1])
      elsif ARGV[0] == 'file'
        fix_file_rely_lib(ARGV[1])
      else
        puts "please input command [preview,do,previewfile,file,view] "
      end
    end
    

      合理的脚本代码可以有效的提高工作效率,减少重复劳动。


      欢迎光临知了软件开发网络平台,本公司定制开发各类软件,主要方向为桌面专业软件开发和插件定制开发,桌面软件主要包括文字图形识别类软件,信息管理类软件,3D打印类软件,视频类软件以及其它涉及专业的各类图形图像处理软件。插件包含AE插件,AI插件,PS插件,PDF插件,3DMAX插件以及Word,Excel等Office插件开发。详情请咨询,微信QQ:312117271,手机:18928899728,邮箱: anjingzhi_sea@163.com.
    公司网址:http://www.zhiliaos.com

    展开全文
  • Ubuntu设置当前目录加载so动态库

    千次阅读 2018-10-15 14:24:53
    Ubuntu设置当前目录加载so动态库
  • 之所以想搞明白这个是因为之前写的qt...首先,你的exe文件在编译的时候指定了它需要哪些部分的dll文件,在应用程序加载dll的时候如果加载错(同名)了dll就会报错 接下来的内容是 1. 参考MSDN,给出Windows下DLL查.
  • linux的excutable在执行的时候...windows加载动态库的时候,缺省是首先加载本地目录下的动态库,然后再搜索windows/system和windows/system32目录windows动态库搜索顺序,虽然有可能会造成潜在的混乱,但是对...
  • linux的excutable在执行的时候缺省是先...windows加载动态库的时候,缺省是首先加载本地目录下的动态库,然后再搜索windows/system和windows/system32目录windows动态库搜索顺序,虽然有可能会造成潜在的混
  • linux的excutable在执行的时候缺省是...windows加载动态库的时候,缺省是首先加载本地目录下的动态库,然后再搜索windows/system和windows/system32目录windows动态库搜索顺序,虽然有可能会造成潜在的混乱,但是
  • linux的excutable在执行的时候缺省是...windows加载动态库的时候,缺省是首先加载本地目录下的动态库,然后再搜索windows/system和windows/system32目录windows动态库搜索顺序,虽然有可能会造成潜在的混乱,但是
  • windows加载动态库的时候,缺省是首先加载本地目录下的动态库,然后再搜索windows/system和windows/system32目录windows动态库搜索顺序,虽然有可能会造成潜在的混乱,但是对于开发和测试无疑是比较方便的,...
  • linux的excutable在执行的时候缺省是...windows加载动态库的时候,缺省是首先加载本地目录下的动态库,然后再搜索windows/system和windows/system32目录windows动态库搜索顺序,虽然有可能会造成潜在的混乱,但是
  • 摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系 统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,便于模块化管理。但不同操作系统的动态库...
  • linux的excutable在执行的时候缺省...windows加载动态库的时候,缺省是首先加载本地目录下的动态库,然后再搜索windows/system和windows/system32目录windows动态库搜索顺序,虽然有可能会造成潜在的混乱,但是对于
  • 正文: linux的excutable在执行的时候缺省是先搜索/lib和/usr/lib这两个目录,然后按照ld.so.conf里面的配置搜索绝对路径,linux...windows加载动态库的时候,缺省是首先加载本地目录下的动态库,然后再搜索window
  • 摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系统 中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,便于模块化管理。但不同操作系统的动态库...
  • Windows动态库和静态库的总结

    千次阅读 2016-01-24 00:29:35
    Windows下的动态库编程并不很熟悉。下午利用一点时间写了个原型,过程中想到许多问题,网上搜到许多文章,学到不少知识,但感觉比较繁杂,于是决定理一理,就有了这篇博文。
  • 然后按下列顺序搜索 DLL:  1、当前进程的可执行模块所在的目录。 GetMoudleFileName 2、当前目录。 GetCurrentDirectory 3、Windows 系统目录。GetSystemDirectory 函数检索此目录的路径。  4、Windows 目录...
  • 文章出处:http://www.diybl.com/course/6_system/linux/Linuxjs/2007926/73949.html linux的excutable在执行的时候缺省是先搜索/lib和/usr/lib这两个目录,然后...windows加载动态库的时候,缺省是首先加载本地目录
  • 摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,便于模块化管理。但不同操作系统的动态库...
  • windows加载动态库---LoadLibrary返回126

    千次阅读 2018-09-12 10:04:05
    前几天,在联网测试三方的dll,但是出现dll放到exe目录下面可以正常加载,如果单独放一个目录却出现126错误代码,找不到指定的模块。 由于三方dll使用zlib版本和exe使用的zlib版本不同,所以三方的dll又不能放到exe...
  • 摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系 统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,便于模块化管理。但不同操作系统的动态库...
  • 一、如何让linux加载当前目录动态库 linux的excutable在执行的时候缺省是先...windows加载动态库的时候,缺省是首先加载本地目录下的动态库,然后再搜索windows/system和windows/system32目录windows动态库...
  • 为何Windows下的动态库总伴随一个静态库? 今天同学来问了一个问题:Visual Studio中生成的动态库总是伴随着一个静态库文件,我把这两个文件同样进行重命名之后还能不能使用? 我对VS下的动态库的生成并...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 62,258
精华内容 24,903
关键字:

windows动态库加载目录顺序