修改程序加载动态库搜寻路径的三种可行方法

合集下载

动态链接库教程

动态链接库教程

动态链接库教程动态链接库(Dynamic Link Library,简称DLL)是一种可由多个程序共享的库文件,它包含了一组函数和数据,可以在程序运行时加载和调用。

DLL 文件可用于将一些通用的功能封装成函数,供多个程序调用,从而提高代码的复用性和开发效率。

本文将详细介绍动态链接库的概念、使用方法以及制作过程。

一、动态链接库的概念动态链接库是一种包含了函数和数据的库文件,它可以在程序运行时被加载和调用。

与静态链接库相比,动态链接库的优势在于节省内存空间和提高代码的复用性。

当多个程序需要使用同一个功能时,它们可以共享同一个DLL文件,避免了重复编写相同的代码。

二、动态链接库的使用方法在使用动态链接库之前,我们首先需要了解动态链接库的编译、加载和调用过程。

1.编译动态链接库在创建 DLL 文件时,我们需要按照一定的规范编写代码,并将其编译成 DLL 文件。

编译时,需要指定导出函数的修饰符(如 _stdcall、_cdecl等),以及导出函数的声明。

这些步骤可以在开发环境(如Visual Studio)中完成。

2.加载动态链接库在程序运行时,需要加载 DLL 文件。

我们可以通过调用LoadLibrary 函数来加载 DLL,该函数返回一个句柄,表示 DLL 的实例。

加载 DLL 文件后,我们可以通过该句柄获取 DLL 中导出函数的地址。

3.调用动态链接库在获取到DLL中导出函数的地址后,我们可以通过函数指针来调用DLL中的函数。

通过函数指针,程序可以跳转到DLL中执行指定的函数,从而完成相应的功能。

三、制作动态链接库下面以C++语言为例,简单介绍如何制作一个动态链接库。

1.创建DLL工程在 Visual Studio 中创建一个 DLL 项目,选择 DLL(动态链接库)作为项目类型。

在项目中添加需要导出的函数,并在头文件中进行声明。

2.编写导出函数在 DLL 项目中编写需要导出的函数,并在函数前添加修饰符(如_stdcall、_cdecl等)。

动态链接库的使用方法

动态链接库的使用方法

动态链接库的使用方法动态链接库(Dynamic Link Library,DLL)是Windows系统中一种常见的文件类型,用于存储可被程序在运行时动态加载的函数和数据。

它可以提供代码和资源的共享,使得程序的安装包更小,节省了系统资源。

使用动态链接库有以下几个优点:1.模块化:将程序代码和资源划分为独立的模块,便于开发和维护。

2.共享性:多个程序可以共享同一个动态链接库,减少重复的代码和数据的存储。

3.动态加载:可以在程序运行时动态地加载和卸载动态链接库,提高了程序的灵活性和可扩展性。

1.创建动态链接库:使用C/C++编程语言可以创建动态链接库。

首先,在开发环境中创建新的DLL项目,并选择动态链接库的类型。

在项目中添加需要的代码和资源,并编写相应的函数和数据接口。

将这些接口封装在一个头文件中,并在源文件中实现具体的功能。

最后,编译项目生成动态链接库文件(.dll 文件)。

2.导出函数和数据:在动态链接库中,明确指定哪些函数和数据需要被其他程序调用。

在函数和数据的声明前加上__declspec(dllexport)关键字即可。

例如:```C++__declspec(dllexport) int Add(int a, int b);```3.调用动态链接库:在其他程序中调用动态链接库中的函数和数据,需要先导入相应的函数和数据。

使用C/C++编程语言可以创建一个头文件,其中包含要导入的函数和数据的声明。

例如:```C++__declspec(dllimport) int Add(int a, int b);__declspec(dllimport) extern double PI;```然后,在使用这些函数和数据的源文件中包含这个头文件即可。

4.加载和卸载动态链接库:在程序运行时,需要动态地加载动态链接库,并在使用完之后卸载。

可以使用LoadLibrary函数来加载动态链接库,使用FreeLibrary函数来卸载动态链接库。

总结c获取当前路径的7种方法

总结c获取当前路径的7种方法

总结C#获取当前路径的7种方法C#获取当前路径的方法如下:1.-获取模块的完整路径。

2.-获取和设置当前目录(该进程从中启动的目录)的完全限定目录。

3.-获取应用程序的当前工作目录。

这个不一定是程序从中启动的目录啊,有可能程序放在C:\www里,这个函数有可能返回C:\Documents and Settings\ZYB\,或者C:\Program Files\Adobe\,有时不一定返回什么东东,我也搞不懂了。

4.-获取程序的基目录。

5.-获取和设置包括该应用程序的目录的名称。

6.-获取启动了应用程序的可执行文件的路径。

效果和2、5一样。

只是5返回的字符串后面多了一个"\"而已7.-获取启动了应用程序的可执行文件的路径及文件名,效果和1一样。

对于Windows程序和Web 应用程序来说,他们运行的路径是不一样的,所以关键是判断当前运行的程序是哪种程序.于是我们可以使用如下的代码1string path = "";23if ( ==45...{67path = ;819}1011else1213...{1415path = + "Bin\";1617}这样如果我们写了一个类库,类库中用到了Assembly.LoadFrom,由于是通用类库,所以可能用到Windows程序中也可能用到Web中,那么用上面的代码就很方便了.1、Server.MapPath2、3、C#获取当前路径方法2可以应用于控制台应用程序,WinForm应用程序,Windows服务,方法1可以应用于Web应用程序,方法3都可以应用。

但方法3是加载应用程序的路径。

如果是Web应用程序,取得的路径是:C:\WINDOWS\\Framework\ Files目录。

所以Web项目还是使用Server.MapPath吧。

否则建议使用方法2。

如果自己新建类库。

可以加入对C#获取当前路径的方法就总结到这里,希望对大家有所帮助。

c++中生成动态库,外工程调用动态库的配置方法

c++中生成动态库,外工程调用动态库的配置方法

C++中,由工程生成、调用dll的方法一、由工程生成dllSetp1:右键点开工程属性-常规,将配置类型中exe改为dll动态库,随后点击确认。

图1 将exe类型改为dllStep2:右键点开工程属性-c++/c中的预处理器,点开预处理器中的定义,点击编辑,在编辑框中加入:工程名_EXPORTS(大写)图2 在预处理器中定义,加入工程名_EXPORTSStep3:在工程下的头文件筛选器中,新建全局头文件,头文件格式如下:图3在项目中新建全局头文件Step4:把第三步生成的头文件,#include到同工程中的每一个头文件中,即该工程中的每一个头文件均引用全局头文件图4 把第三步新建的头文件引入项目的其余头文件中Step5:在各头文件中,在类的标识符后面,类名的前面;或者函数名的前面加入ccc_API(工程名称_API)图5 在各头文件的类声明中加入工程名称_API Setp6:右键工程属性,点击c++/c常规中的附加包含目录,选择头文件所在目录,点击确认。

图6 附加包含目录Step7:右键工程清理,随后点击生成,当命令栏显示成功生成时,表示成功生成该工程的dll和lib文件图7 点击生成产生dll和lib文件%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 可在工程文件的Debug文件夹中找到dll和lib文件,在工程文件名,同文件名下的文件夹中找到头文件,若外部程序需要调用此工程,仅需将以上文件导出即可。

图8 外部调用程序二、由外部工程调用dllStep1:右键调用dll文件的工程属性,点击链接器-常规-附加库目录,添加包含动态链接库涉及的头文件和lib文件的文件夹。

图9 调入文件的文件夹设定Step2:右键工程属性,点击链接器-输入-附加依赖项,点击编辑,添加调入动态库的Lib文件名称,格式为工程名,lib(和生成库的名称一致)图10 附加依赖项配置Step3:将导入的dll文件,放在应用工程的.EXE文件所在文件夹中,即解决方案的Debug(release)中。

linux动态库(.so)搜索路径(目录)设置方法

linux动态库(.so)搜索路径(目录)设置方法

linux动态库(.so)搜索路径(⽬录)设置⽅法在Linux 中,动态库的搜索路径除了默认的搜索路径外,还可通过三种⽅法来指定:⽅法⼀:在配置⽂件/etc/ld.so.conf中指定动态库搜索路径;⽅法⼆:通过环境变量LD_LIBRARY_PATH指定动态库搜索路径;⽅法三:在编译⽬标代码时指定该程序的动态库搜索路径。

众所周知,Linux动态库的默认搜索路径是/lib和/usr/lib。

动态库被创建后,⼀般都复制到这两个⽬录中。

当程序执⾏时需要某动态库,并且该动态库还未加载到内存中,则系统会⾃动到这两个默认搜索路径中去查找相应的动态库⽂件,然后加载该⽂件到内存中,这样程序就可以使⽤该动态库中的函数,以及该动态库的其它资源了。

在Linux 中,动态库的搜索路径除了默认的搜索路径外,还可以通过以下三种⽅法来指定。

⽅法⼀:在配置⽂件/etc/ld.so.conf中指定动态库搜索路径。

vi /etc/ld.so.conf添加 lib⽬录ldconfig⽅法⼆:通过环境变量LD_LIBRARY_PATH指定动态库搜索路径。

export LD_LIBRARY_PATH=”LD_LIBRARY_PATH:/opt/”⽅法三:在编译⽬标代码时指定该程序的动态库搜索路径。

还可以在编译⽬标代码时指定程序的动态库搜索路径。

通过gcc 的参数”-Wl,-rpath,”指定其中⽅法三可以避免安装部署的⿇烦⽅法三⽰例假设main.cpp,hello.h,hello.cpp,其中main.cpp调⽤了hello类中的⽅法1 ⽣成hello.sog++ -shared hello.cpp -o libhello.so2 编译main.cpp,并链接,并指定运⾏时libhello.so的位置 g++ main.cpp -lhello -L./ -Wl,-rpath=./ -o main值得⼀提的是,如果采⽤带版本号的库,例如libhello.so.2链接命令可使⽤g++ main.cpp libhello.so.2 -L./ -Wl,-rpath=./ -o main2)加⼊第⼆个so库g++ main.cpp -L./second/ -Wl,-rpath=./second/ -lsecond -L./hello/ -Wl,-rpath=./hello/ -lhello -o mainps,遇到过⼀个奇怪的问题,就是假设libhello.so还⽤到了libother.so,由于在/etc/ld.so.conf⾥配置错误了libother.so的⽬录路径,导致⼀直产⽣undefined reference to错误,但是在⼯程⾥对libother⽬录路径配置是正确的,有可能于查找路径顺序有关。

静态链接与动态链接库的查找顺序

静态链接与动态链接库的查找顺序

静态链接与动态链接库的查找顺序
静态库链接时搜索路径顺序:
1. ld会去找GCC命令中的参数-L
2. 再找gcc的环境变量LIBRARY_PATH
3. 再找内定⽬录 /lib /usr/lib /usr/local/lib 这是当初compile gcc时写在程序内的
动态链接时、执⾏时搜索路径顺序:
1. 编译⽬标代码时指定的动态库搜索路径
2. 环境变量LD_LIBRARY_PATH指定的动态库搜索路径
3. 配置⽂件/etc/ld.so.conf中指定的动态库搜索路径
4. 默认的动态库搜索路径/lib
5. 默认的动态库搜索路径/usr/lib
有关环境变量:
LIBRARY_PATH环境变量:指定程序静态链接库⽂件搜索路径
LD_LIBRARY_PATH环境变量:指定程序动态链接库⽂件搜索路径
头⽂件:
系统预设⽬录
系统预设的头⽂件⽬录是通过环境变量C_INCLUDE_PATH来设置的,这个变量的值要在执⾏配置命令configure之前设置。

编译器预设⽬录
编译器预设⽬录由编译器⾃⼰决定的,由程序代码决定的,这是不需要⼯⼈设置或指定的。

可以总结出头⽂件的查找路径及优先顺序:
1.如果源⽂件中使⽤双引号来包含头⽂件,则⾸先在源⽂件当前⽬录查找头⽂件。

2.如果编译时使⽤"-I/some/dir",则在/some/dir中查找。

3.如果设置了环境变量C_INCLUDE_PATH,则在指定的⽬录中查找。

4.最后在编译器预设的路径中查找,这是不需要指定的,编译时⼀定会在该路径中搜索所需的头⽂件。

linux设置动态库路径和环境变量

linux设置动态库路径和环境变量

linux设置动态库路径和环境变量linux安装源码编译出来的库后,如何让系统默认识别到,如编译后安装在/usr/local/aarch64_qt5.12.0 下1、设置动态库链接配置如果不设置动态库连接,系统就找不到需要的*.so,导致软件执⾏失败。

可以ldd⼀下,如:pi@NanoPi-NEO-Plus2:~$ ldd untitledlinux-vdso.so.1 => (0x0000ffffba839000)libQt5Widgets.so.5 => not foundlibQt5Gui.so.5 => not foundlibQt5Core.so.5 => not foundlibpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000ffffba7e2000)libstdc++.so.6 => /usr/lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000ffffba653000)libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000ffffba5a6000)libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000ffffba585000)libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffffba43e000)/lib/ld-linux-aarch64.so.1 (0x0000ffffba80e000)最笨的⽅法就是将编译出来对应的so 拷贝到/usr/lib或者/lib下,如果对应的so很多,那么就凉凉了。

设置⽅法:1)在/etc/ld.so.conf.d路径下,创建动态库配置⽂件*.conf,例如:sudo vim /etc/ld.so.conf.d/Qt5.conf在⽂件中添加:/usr/local/aarch64_qt5.12.0/lib2)加载动态库配置执⾏命令:sudo ldconfigpi@NanoPi-NEO-Plus2:~$ ldd untitledlinux-vdso.so.1 => (0x0000ffffa4b1a000)libQt5Widgets.so.5 => /usr/local/aarch64_qt5.12.0/lib/libQt5Widgets.so.5 (0x0000ffffa451d000)libQt5Gui.so.5 => /usr/local/aarch64_qt5.12.0/lib/libQt5Gui.so.5 (0x0000ffffa4039000)libQt5Core.so.5 => /usr/local/aarch64_qt5.12.0/lib/libQt5Core.so.5 (0x0000ffffa39ed000)libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000ffffa39c1000)libstdc++.so.6 => /usr/lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000ffffa3832000)libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000ffffa3785000)libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000ffffa3764000)libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffffa361d000)libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000ffffa360a000)/lib/ld-linux-aarch64.so.1 (0x0000ffffa4aef000)2、设置环境变量执⾏相关程序时,不需要切换到指定⽬录才能执⾏,可以在任意⽬录下执⾏。

修改程序加载动态库搜寻路径的三种可行方法

修改程序加载动态库搜寻路径的三种可行方法

1,影响整个系统里所有程序的修改以ubuntu为例,在/etc/ld.so.conf.d目录下新增一个配置文件,名词任意,比如为mylib.conf:lenky@Ubuntu:/etc/ld.so.conf.d$ sudo vi mylib.conf[sudo] password for lenky:lenky@Ubuntu:/etc/ld.so.conf.d$ cat mylib.conf/home/lenky/lib/usr/lib/otherapp/lib指定了动态库的加载路径为/home/lenky/lib执行ldconfig进行更新/etc/ld.so.cache:lenky@Ubuntu:/etc/ld.so.conf.d$ sudo ldconfig也就是说/etc/ld.so.cache里保存了系统在执行应用程序加载动态库的默认搜索路径。

动态库的搜索是有先后顺序的,先找到谁就使用谁。

2,影响特定环境下所有程序的修改这利用的是LD_LIBRARY_PATH环境变量,在程序执行而加载动态库时,首先搜索的是LD_LIBRARY_PATH指定的路径,然后再是/etc/ld.so.cache包含的系统默认搜索路径。

因此,如果主动指定某环境下的LD_LIBRARY_PATH环境变量,那么就能够影响该环境下的所有应用程序执行时加载动态库的搜索路径。

3,影响单个程序的修改如果我只想指定某一个程序myexe的动态库搜索路径,比如我要把某个程序分发给用户,但又不知道用户电脑上是否安装了对应的依赖库或依赖库版本是否一致等,那么我干脆就提供这份库,并让我的程序myexe在执行时链接到我所提供的这份库,但又不能影响到用户电脑上的其他程序。

那么根据第2点的变通办法有:a,创建一个脚本wrapper,在这个脚本里export LD_LIBRARY_PATH或setenvLD_LIBRARY_PATH环境变量,然后执行程序。

将动态链接库文件添加到VC程序中

将动态链接库文件添加到VC程序中

将动态链接库文件添加到VC程序中应用程序使用DLL可以采用两种方式:一种是隐式链接,另一种是显式链接。

在使用DLL之前首先要知道DLL中函数的结构信息。

Visual C++6.0在VC\bin目录下提供了一个名为Dumpbin.exe的小程序,用它可以查看DLL文件中的函数结构。

另外,Windows系统将遵循下面的搜索顺序来定位DLL: 1.包含EXE文件的目录,2.进程的当前工作目录,3.Windows系统目录,4.Windows目录,5.列在Path环境变量中的一系列目录。

(一)隐式链接隐式链接就是在程序开始执行时就将DLL文件加载到应用程序当中。

实现隐式链接很容易,只要将导入函数关键字_declspec(dllimport)函数名等写到应用程序相应的头文件中就可以了。

下面的例子通过隐式链接调用MyDll.dll库中的Min函数。

首先生成一个项目为TestDll,在DllTest.h、DllTest.cpp文件中分别输入如下代码://Dlltest.h#pragma comment(lib,"MyDll.lib")extern "C"_declspec(dllimport) int Max(int a,int b);extern "C"_declspec(dllimport) int Min(int a,int b);//TestDll.cpp#include<stdio.h>#include"Dlltest.h"void main(){int a;a=min(8,10)printf("比较的结果为%d\n",a);}在创建DllT est.exe文件之前,要先将MyDll.dll和MyDll.lib拷贝到当前工程所在的目录下面,也可以拷贝到windows的System目录下。

如果DLL使用的是def文件,要删除T estDll.h文件中关键字extern "C"。

solaris动态链接库搜索路径

solaris动态链接库搜索路径
4.3.4.1 在生成时指定动态库
生成可执行文件时,链接程序会在可执行文件本身中记录共享库的路径。这些搜索路径可以用 -Rpath 选项指定。这一点与 -Ldir 选项相反,该选项在生成时指示到哪里查找 -llibrary 选项所指定的库,但不会将该路径记录到二进制可执行文件中。
使用 dump 命令可以查看创建可执行文件时内置的目录路径。
libfminvai.so.1 =&gt; /opt/SUNWspro/lib/libfminvai.so.1
libfmaxvai.so.1 =&gt; /opt/SUNWspro/lib/libfmaxvai.so.1
libfsu.so.1 =&gt; /opt/SUNWspro/lib/libfsu.so.1
当动态链接程序找不到所需库的位置时,它会发出以下错误消息:
ld.so: prog: fatal: libmylib.so: can’t open file:
此消息表明这些库不在其应在的位置。您也许在生成可执行文件时指定了共享库的路径,但这些库随后已被移动。例如,您可
用户使用 -Rpath 指定的路径
*
/opt/SUNWspro/lib/
*
/usr/lib 标准 UNIX 缺省值
这些搜索路径被内置于可执行文件中。
4.3.2 LD_LIBRARY_PATH 环境变量
使用 LD_LIBRARY_PATH 环境变量指定链接程序应在哪些目录路径中搜索用 -llibrary 选项指定的库。
也就是说,如果使用多个 -L 调用编译器,如下所示:
f95 ... -Lpath1 ... -Lpathn ...
则搜索顺序是:

配置动态库路径的四种方法

配置动态库路径的四种方法

配置动态库路径的四种方法配置动态库路径是在编译和运行程序时告诉系统动态库文件所在位置的一种方式。

动态库是一些可被多个程序共享的代码和数据的集合,使用动态库可以提高程序的可维护性和可扩展性。

本文将介绍四种配置动态库路径的方法。

一、使用环境变量LD_LIBRARY_PATHLD_LIBRARY_PATH是一个环境变量,用来指定动态库文件的搜索路径。

当程序在运行时需要加载动态库时,系统会在LD_LIBRARY_PATH指定的路径下查找动态库文件。

可以通过export命令设置LD_LIBRARY_PATH环境变量,例如:export LD_LIBRARY_PATH=/path/to/dynamic/libs这样,系统就会在"/path/to/dynamic/libs"路径下查找动态库文件。

二、使用rpath选项rpath是编译时指定动态库搜索路径的一种选项。

通过在编译时加上-rpath选项,可以告诉编译器在指定路径下搜索动态库文件。

例如,使用gcc编译C程序时加上-rpath选项:gcc -o program program.c -Wl,-rpath=/path/to/dynamic/libs这样,编译后的程序在运行时会在"/path/to/dynamic/libs"路径下搜索动态库文件。

三、使用配置文件ld.so.confld.so.conf是一个配置文件,用来指定系统动态库的搜索路径。

可以通过编辑该文件,添加动态库搜索路径。

打开ld.so.conf文件,添加一行:/path/to/dynamic/libs保存文件后,执行以下命令使配置生效:ldconfig这样,系统就会在"/path/to/dynamic/libs"路径下搜索动态库文件。

四、使用LD_PRELOAD环境变量LD_PRELOAD是一个环境变量,用来指定在程序加载时优先加载的动态库文件。

(整理)C中如何调用动态链接库DLL.

(整理)C中如何调用动态链接库DLL.

C#中如何调用动态链接库DLL动态链接库(也称为DLL,即为“Dynamic Link Library”的缩写)是Microsoft Windows 最重要的组成要素之一,打开Windows系统文件夹,你会发现文件夹中有很多DLL文件,Windows就是将一些主要的系统功能以DLL模块的形式实现。

动态链接库是不能直接执行的,也不能接收消息,它只是一个独立的文件,其中包含能被程序或其它DLL调用来完成一定操作的函数(方法。

注:C#中一般称为“方法”),但这些函数不是执行程序本身的一部分,而是根据进程的需要按需载入,此时才能发挥作用。

DLL只有在应用程序需要时才被系统加载到进程的虚拟空间中,成为调用进程的一部分,此时该DLL也只能被该进程的线程访问,它的句柄可以被调用进程所使用,而调用进程的句柄也可以被该DLL所使用。

在内存中,一个DLL只有一个实例,且它的编制与具体的编程语言和编译器都没有关系,所以可以通过DLL来实现混合语言编程。

DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。

下面列出了当程序使用 DLL 时提供的一些优点:[1]1) 使用较少的资源当多个程序使用同一个函数库时,DLL 可以减少在磁盘和物理内存中加载的代码的重复量。

这不仅可以大大影响在前台运行的程序,而且可以大大影响其他在 Windows 操作系统上运行的程序。

2) 推广模块式体系结构DLL 有助于促进模块式程序的开发。

这可以帮助您开发要求提供多个语言版本的大型程序或要求具有模块式体系结构的程序。

模块式程序的一个示例是具有多个可以在运行时动态加载的模块的计帐程序。

3) 简化部署和安装当 DLL 中的函数需要更新或修复时,部署和安装 DLL 不要求重新建立程序与该 DLL 的链接。

此外,如果多个程序使用同一个 DLL,那么多个程序都将从该更新或修复中获益。

当您使用定期更新或修复的第三方 DLL 时,此问题可能会更频繁地出现。

c编译,调用动态连接库(.so文件)

c编译,调用动态连接库(.so文件)

c编译,调⽤动态连接库(.so⽂件)在“”中,我在每⼀篇都会有⼀个C程序,⽤于实现算法和数据结构 (⽐如栈和相关的操作)。

在同⼀个程序中,还有⽤于测试的main()函数,结构体定义,函数原型,typedef等等。

这样的做法⾮常不“环保”。

算法的实际运⽤和算法的实现混在⼀起。

如果我想要重复使⽤之前的源程序,必须进⾏许多改动,并且重新编译。

最好的解决⽅案是实现模块化: 只保留纯粹的算法实现,分离头⽂件,并编译⼀个库(library)。

每次需要使⽤库的时候(⽐如使⽤栈数据结构),就在程序中include头⽂件,连接库。

这样,不需要每次都改动源程序。

我在这⾥介绍如何在UNIX环境中创建共享库 (shared library)。

UNIX下,共享库以so为后缀(shared object)。

共享库与Windows下的DLL类似,是在程序运⾏时动态连接。

多个进程可以连接同⼀个共享库。

实现将⼀个⾃⼰编写的Hello.c⽂件打包成libHello.so动态库,并通过gcc编译⼯具实现⽤⼀个test.c程序调⽤libHello.so和⾃定义头⽂件Hello.h的过程。

具体程序代码如下://Hello.h⽂件#include <stdio.h>void printhello();//Hello.c⽂件#include <stdio.h>void printhello(){puts("Hello World!");}//test.c⽂件#include “Hello.h”int main(){printhello();return 0;}具体操作过程:第⼀步:将⽂件Hello.c编译成⼀个动态库:libHello.so,执⾏命令如下:$ gcc Hello.c -fPIC -shared -o libHello.so-shared:该选项指定⽣成动态连接库(让连接器⽣成T类型的导出符号表,有时候也⽣成弱连接W类型的导出符号),不⽤该标志外部程序⽆法连接,相当于⼀个可执⾏⽂件;-fPIC:PIC指Position Independent Code,表⽰编译为位置独⽴的代码,不⽤此选项的话编译后的代码是位置相关的,所以动态载⼊时是通过代码拷贝的⽅式来满⾜不同进程的需要,⽽不能达到真正代码段共享的⽬的。

linux给运行程序指定动态库路径

linux给运行程序指定动态库路径

linux给运⾏程序指定动态库路径1. 连接和运⾏时库⽂件搜索路径的设置库⽂件在连接(静态库和共享库)和运⾏(仅限于使⽤共享库的程序)时被使⽤,其搜索路径是在系统中进⾏设置的。

⼀般 Linux 系统把/lib 和 /usr/lib 两个⽬录作为默认的库搜索路径【debian可以在⾥⾯搜索出qt,因为debian默认安装了qt程序运⾏依赖库】,所以使⽤这两个⽬录中的库时不需要进⾏设置搜索路径即可直接使⽤。

对于处于默认库搜索路径之外的库,需要将库的位置添加到库的搜索路径之中。

设置库⽂件的搜索路径有下列两种⽅式,可任选其⼀使⽤:(1). 在 /etc/ld.so.conf ⽂件中添加库的搜索路径。

(或者在/etc/ld.so.conf.d 下新建⼀个.conf⽂件,将搜索路径⼀⾏⼀个加⼊-junziyang)将⾃⼰可能存放库⽂件的路径都加⼊到/etc /ld.so.conf中是明智的选择添加⽅法也极其简单,将库⽂件的绝对路径直接写进去就OK了,⼀⾏⼀个。

例如:/usr/X11R6/lib/usr/local/lib/opt/lib需要注意的是:这种搜索路径的设置⽅式对于程序连接时的库(包括共享库和静态库)的定位已经⾜够了,但是对于使⽤了共享库的程序的执⾏还是不够的。

这是因为为了加快程序执⾏时对共享库的定位速度,避免使⽤搜索路径查找共享库的低效率,所以是直接读取库列表⽂件 /etc/ld.so.cache 从中进⾏搜索的。

/etc/ld.so.cache是⼀个⾮⽂本的数据⽂件,不能直接编辑,它是根据 /etc/ld.so.conf 中设置的搜索路径由 /sbin/ldconfig 命令将这些搜索路径下的共享库⽂件集中在⼀起⽽⽣成的(ldconfig 命令要以 root 权限执⾏)。

因此,为了保证程序执⾏时对库的定位,在 /etc/ld.so.conf 中进⾏了库搜索路径的设置之后,还必须要运⾏ /sbin/ldconfig 命令更新 /etc/ld.so.cache⽂件之后才可以。

Linux动态库.so文件加载搜索路径详解

Linux动态库.so文件加载搜索路径详解

Linux动态库.so⽂件加载搜索路径详解因为这⼀段要集成代码,除了组内的,还有组间的,还有第三⽅的,这⾥⾯都采⽤动态库的⽅式进⾏链接,但是在集成的时候经常出现so⽂件找不到的问题,使⽤ldd查看,也是某些so⽂件找不到。

有的⽂件明明就在那⾥,但是却找不到,针对这些⿇烦,我们头疼医头脚疼医脚,暂时解决了这些问题,但是并没有从根本上了解清楚,解决思路单⼀,都是修改ld.so.conf⽂件,然后执⾏ldconfig。

今天看了帖⼦,就顺便把这个so⽂件查找顺序的问题彻底了解了,省得后⾯再出问题的时候,⼜修改ld.so.conf去解决。

⾸先,我们要知道so⽂件是怎么查找的。

动态链接器ld-.so按照下⾯的顺序来搜索需要的动态共享库对于elf格式的可执⾏程序,是由ld-linux.so*来完成的,它先后搜索elf⽂件的DT_RPATH段(不可控) --> 环境变量LD_LIBRARY_PATH --> /etc/ld.so.cache⽂件列表 --> /lib/和/usr/lib ⽬录找到库⽂件后载⼊内存。

1.ELF可执⾏⽂件中动态段中DT_RPATH所指定的路径。

这实际上是通过⼀种不算很常⽤,却⽐较实⽤的⽅法所设置的:编译⽬标代码时,可以对gcc/g++加⼊链接参数“-Wl,-rpath”指定动态库搜索路径;实际上,这种⽅式我们基本没⽤过,所以这个查找⽅式基本不会起作⽤。

2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;⼀般需要修改⽤户的bashrc或者系统的profile⽂件,⼀般⼩程序也不会修改这俩⽂件,除⾮是对于/usr/local/lib这种通⽤的路径,有可能会放进去,但也不⼀定。

3./etc/ld.so.cache中所缓存的动态库路径(如果⽀持ld.so.cache的话,这个⽂件还不⼩有⼏百k,有⼀⼤堆具体的so⽂件)。

这可以通过修改配置⽂件/etc/ld.so.conf中指定的动态库搜索路径来改变;4.默认的动态库搜索路径/lib或者是/lib64;5.默认的动态库搜索路径/usr/lib或者是/usr/lib64简单例⼦ printf.cpp#include <iostream>void Print(){std::cout<<"Hello,world!"<<std::endl;}动态库编译g++ printf.cpp -shared -fPIC -o libprintf.somain.cpp#include <iostream>#include <printf.cpp>extern void Print();int main(){Print();return 0;}1)指定动态库的搜索路径为当前本地路径g++ main.cpp -L./ -lprintf -Wl,-rpath=./查看可执⾏程序,内部的细节readelf -d a.outDynamic section at offset 0xe08 contains 26 entries:Tag Type Name/Value0x0000000000000001 (NEEDED) Shared library: [libprintf.so]0x0000000000000001 (NEEDED) Shared library: [libc.so.6]0x000000000000000f (RPATH) Library rpath: [./]指定了动态库链接的位置2)增加系统变量export LD_LIBRARY_PATH=./g++ main.cpp -L./ -lprintf去掉指定⽬录指令unset LD_LIBRARY_PATHecho $LD_LIBRARY_PATH所以,修复so⽂件找不到的⽅法就是将动态库所在⽬录的绝对路径加到动态载⼊器搜索序的任⼀次序中,下⾯说具体实现⽅法:⽅法1:拷贝⾃⼰制作的共享库到/lib或/usr/lib,不推荐⽅法2:将动态库所在⽬录的绝对路径添加到系统环境变量中2.1、将动态库所在⽬录的绝对路径临时添加到环境变量中(随终端关闭失效)export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/chiliast/homework/day03/shared/lib2.2、将动态库所在⽬录的绝对路径设置到~/.bashrc或/etc/profile中(永久⽣效)⽤户级别:追加库路径到~/.bashrc⽂件尾export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/chiliast/homework/day03/shared/libsource ~/.bashrc 或 . ~/.bashrc使配置⽣效系统级别:追加库路径到/etc/profile⽂件尾export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/chiliast/homework/day03/shared/libsource /etc/profile 或 ./etc/profile使配置⽣效⽅法3:将动态库所在⽬录的绝对路径添加到 /etc/ld.so.cache⽂件中(2步实现)编辑/etc/ld.so.conf⽂件,加⼊库⽂件所在⽬录的路径运⾏ldconfig (需要super user权限),该命令会重建/etc/ld.so.cache⽂件。

vs2008动态库加载方法

vs2008动态库加载方法

一、创建新的动态链接库(DLL)项目1.从“File”菜单中,选择“New”,然后选择“Project…”。

如下图:2.在“项目类型”窗格中,选择“Visual C++”下的“Win32”。

3.在“模板”窗格中,选择“Win32 Console Application”。

4.为项目选择一个名称,如MathFuncsDll,并将其键入“Name:”字段。

为解决方案选择一个名称,如DynamicLibrary,并将其键入“SolutionName:”字段。

如下图:5.单击“OK”启动Win32 应用程序向导。

在“Win32 应用程序向导”对话框的“概述”页中,单击“NEXT”。

6.在“Win32 应用程序向导”中的“应用程序设置”页中,选择“应用程序类型”下的“DLL”(如果可用),或者选择“控制台应用程序”(如果“DLL”不可用)。

某些版本的Visual Studio 不支持通过使用向导创建DLL 项目。

您可以稍后对此进行更改,以将项目编译为DLL。

7.在“Win32 应用程序向导”的“应用程序设置”页中,选择“附加选项”下的“空项目”。

8.单击“Finish”创建项目。

如下图:二、向动态链接库添加类1.若要为新类创建头文件,请从“项目”菜单中选择“添加新项…”。

将显示“添加新项”对话框。

在“类别”窗格中,选择“Visual C++”下的“代码”。

在“模板”窗格中选择“头文件(.h)”。

为头文件选择一个名称,如MathFuncsDll.h,并单击“添加”。

将显示一个空白文件。

2.添加一个名为“MyMathFuncs”的简单类,以执行常见的算术运算,如加、减、乘和除。

代码应与以下内容类似:3.// MathFuncsDll.h4.space MathFuncs6.{7. class MyMathFuncs8. {9. public:10. // Returns a + b11. static __declspec(dllexport) double Add(double a,double b);12.13. // Returns a - b14. static __declspec(dllexport) doubleSubtract(double a, double b);15.16. // Returns a * b17. static __declspec(dllexport) doubleMultiply(double a, double b);18.19. // Returns a / b20. // Throws DivideByZeroException if b is 021. static __declspec(dllexport) doubleDivide(double a, double b);22. };}23.请注意此代码方法声明中的__declspec(dllexport) 修饰符。

c程序加载动态库的规则

c程序加载动态库的规则

c程序加载动态库的规则C程序加载动态库的规则动态库是一种在运行时加载的共享库,它允许多个程序共享同一份代码。

在C程序中,加载动态库是非常常见的操作,可以通过一些规则来实现。

1. 动态库的命名规则动态库的命名规则通常是以lib开头,后面跟着库的名称和版本号,最后以.so作为扩展名。

比如,libexample.so是一个动态库文件的命名规则。

2. 动态库的查找路径当程序加载动态库时,会按照一定的顺序在特定的路径中查找动态库文件。

这些路径包括:- 环境变量LD_LIBRARY_PATH中指定的路径- 默认的系统库路径,如/lib和/usr/lib- 应用程序指定的路径,通过-rpath选项指定3. 动态库的加载顺序当程序加载动态库时,会按照一定的顺序加载多个动态库。

加载顺序如下:- 先加载程序本身所需的动态库,如libc.so等- 再加载程序依赖的其他动态库,按照依赖关系从左向右依次加载- 最后加载由LD_PRELOAD环境变量指定的动态库,这些库会覆盖系统默认的库4. 动态库的符号解析在程序加载动态库后,需要解析动态库中的符号以实现函数调用。

符号解析的规则如下:- 先在程序本身中查找符号,如果找到则使用程序本身的符号- 如果程序本身没有定义该符号,则在动态库中查找符号,如果找到则使用动态库中的符号- 如果在动态库中也没有找到符号,则会报符号未定义的错误5. 动态库的版本管理动态库的版本管理是非常重要的,可以通过一些规则来管理动态库的版本。

这些规则包括:- 动态库的命名中包含版本号,如libexample.so.1.0.0- 使用符号链接来管理动态库的版本,如libexample.so指向libexample.so.1,而libexample.so.1指向libexample.so.1.0.0通过以上规则,C程序可以正确加载动态库并进行符号解析,实现函数调用。

加载动态库的规则可以保证程序的可移植性和灵活性,使得多个程序可以共享同一份代码,提高了代码的复用性和维护性。

Linux下指定动态库的加载路径

Linux下指定动态库的加载路径

一、库文件的搜索路径:
1、在配置文件/etc/ld.so.conf中指定动态库搜索路径(需要添加其它库文件的路径,在文件的最后添加具体的路径即可[ 如:/usr/local/lib ],添加后保存退出,然后在命令行ldconfig
2、通过环境变量LD_LIBRARY_PA TH指定动态库搜索路径(当通过该环境变量指定多个动态库搜索路径时,路径之间用冒号":"分隔)
3、在编译目标代码时指定该程序的动态库搜索路径(还可以在编译目标代码时指定程序的动态库搜索路径。

这是通过gcc 的参数"-Wl,-rpath,"指定,当指定多个动态库搜索路径时,路径之间用冒号":"分隔)
4、默认的动态库搜索路径/lib
5、默认的动态库搜索路径/usr/lib
二、搜索的先后顺序是:
1.编译目标代码时指定的动态库搜索路径;
2.环境变量LD_LIBRARY_PA TH指定的动态库搜索路径;
3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;
4.默认的动态库搜索路径/lib;
5.默认的动态库搜索路径/usr/lib。

C#总结(七)动态加载C++动态链接库

C#总结(七)动态加载C++动态链接库

C#总结(七)动态加载C++动态链接库C#调⽤C++ 链接库的⽅式分为静态调⽤和动态调⽤这两种⽅式。

静态调⽤之前的⽂章⾥⾯都有介绍,使⽤.net 提供的DllImport 导⼊相关的C++ 库即可。

请看之前的⽂章,。

今天介绍动态调⽤的⽅法。

很多时候,Dll库的⽬录可能是变化的,或是有些场景,需要根据具体的情况,来动态加载这些Dll库。

这样使⽤静态调⽤的⽅式就很不⽅便,C#中我们经常通过配置动态的调⽤托管Dll,那么是不是也可以这样动态调⽤C++动态链接呢?只要通过LoadLibrary, GetProcess, FreeLibrary这⼏个函数是可以动态调⽤动态链接的(它们包含在kernel32.dll中)。

原理LoadLibrary ( string lpFileName):载⼊指定的动态链接库,并将它映射到当前进程使⽤的地址空间。

载⼊成功后即可访问库内保存的资源,除了LoadLibrary ⽅法,还有⼀个类似的 LoadLibraryEx ⽅法。

GetProcAddress (int hModule, string lpProcName):GetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址。

如果函数调⽤成功,返回值是DLL中的输出函数地址。

如果函数调⽤失败,返回值是NULL。

调⽤函数GetLastError ,得到具体的错误信息。

FreeLibrary ( int hModule) :释放指定的动态链接库,它们早先是⽤LoadLibrary API函数装载的。

GetLastError() :获取错误信息实现1. 将kernel32中的⼏个⽅法封装成本地调⽤类 DLLWrapperusing System;using System.IO;using System.Runtime.InteropServices;namespace Irisking.Basic.Util{///<summary>/// DLLWrapper///</summary>internal class DLLWrapper{[DllImport("kernel32.dll")]private static extern uint GetLastError();///<summary>/// API LoadLibraryEx///</summary>///<param name="lpFileName"></param>///<param name="hReservedNull"></param>///<param name="dwFlags"></param>///<returns></returns>[DllImport("kernel32.dll", EntryPoint = "LoadLibraryEx", SetLastError = true)]private static extern int LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags);///<summary>/// API GetProcAddress///</summary>///<param name="handle"></param>///<param name="funcname"></param>///<returns></returns>[DllImport("Kernel32", EntryPoint = "GetProcAddress", SetLastError = true)]public static extern int GetProcAddress(int handle, string funcname);///<summary>/// API FreeLibrary///</summary>///<param name="handle"></param>///<returns></returns>[DllImport("Kernel32", EntryPoint = "FreeLibrary", SetLastError = true)]private static extern int FreeLibrary(int handle);///<summary>///通过⾮托管函数名转换为对应的委托 , by jingzhongrong///</summary>///<param name="dllModule">通过 LoadLibrary 获得的 DLL 句柄</param>///<param name="functionName">⾮托管函数名</param>///<param name="t">对应的委托类型</param>///<returns>委托实例,可强制转换为适当的委托类型</returns>public static Delegate GetFunctionAddress(int dllModule, string functionName, Type t){int address = GetProcAddress(dllModule, functionName);if (address == 0)return null;elsereturn Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);}///<summary>///将表⽰函数地址的 intPtr 实例转换成对应的委托///</summary>public static Delegate GetDelegateFromIntPtr(IntPtr address, Type t){if (address == IntPtr.Zero)return null;elsereturn Marshal.GetDelegateForFunctionPointer(address, t);}///<summary>///将表⽰函数地址的 int 转换成对应的委托///</summary>public static Delegate GetDelegateFromIntPtr(int address, Type t){if (address == 0)return null;elsereturn Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);}///<summary>///加载sdk///</summary>///<param name="lpFileName"></param>///<returns></returns>public static int LoadSDK(string lpFileName){if (File.Exists(lpFileName)){var hReservedNull = IntPtr.Zero;var dwFlags = LoadLibraryFlags.LOAD_WITH_ALTERED_SEARCH_PATH;var result = LoadLibraryEx(lpFileName, hReservedNull, dwFlags);var errCode = GetLastError();($"LoadSDK Result:{result}, ErrorCode: {errCode}");return result;}return0;}///<summary>///释放sdk///</summary>///<param name="handle"></param>///<returns></returns>public static int ReleaseSDK(int handle){try{if (handle > 0){($"FreeLibrary handle:{handle}");var result = FreeLibrary(handle);var errCode = GetLastError();($"FreeLibrary Result:{result}, ErrorCode: {errCode}");return0;}return -1;}catch (Exception ex){LogHelper.Error(ex);return -1;}}}///<summary>/// LoadLibraryFlags///</summary>public enum LoadLibraryFlags : uint{///<summary>/// DONT_RESOLVE_DLL_REFERENCES///</summary>DONT_RESOLVE_DLL_REFERENCES = 0x00000001,///<summary>/// LOAD_IGNORE_CODE_AUTHZ_LEVEL///</summary>LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010,///<summary>/// LOAD_LIBRARY_AS_DATAFILE///</summary>LOAD_LIBRARY_AS_DATAFILE = 0x00000002,///<summary>/// LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE///</summary>LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040,///<summary>/// LOAD_LIBRARY_AS_IMAGE_RESOURCE///</summary>LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020,///<summary>/// LOAD_LIBRARY_SEARCH_APPLICATION_DIR///</summary>LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 0x00000200,///<summary>/// LOAD_LIBRARY_SEARCH_DEFAULT_DIRS///</summary>LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000,///<summary>/// LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR///</summary>LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x00000100,///<summary>/// LOAD_LIBRARY_SEARCH_SYSTEM32///</summary>LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800,///<summary>/// LOAD_LIBRARY_SEARCH_USER_DIRS///</summary>LOAD_LIBRARY_SEARCH_USER_DIRS = 0x00000400,///<summary>/// LOAD_WITH_ALTERED_SEARCH_PATH///</summary>LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008}}2. 使⽤DLLWrapper类动态读取C++Dll,获得函数指针,并且将指针封装成C#中的委托。

dcc32.exe命令行编译工程搜索路径的问题

dcc32.exe命令行编译工程搜索路径的问题

dcc32.exe命令行编译工程搜索路径的问题dcc32.exe命令行编译工程搜索路径的问题作者:CoolSlob(****************)时间到了23点,说这么一句,是因为时间紧迫,还有很多工作没有做完,但还是坚持花半个小时写这么一篇文章,总是找别人帮忙解决问题,不出点绵薄之力,都不好意思再混下去。

OK,长话短说废话少说,进入正题。

相信对dcc32.exe动过念头的人,都碰到搜索路径的问题:在编辑器中设置好了Search Path,使用dcc32.exe编译工程时愣是提示找不到相关文件,究其原因,还是因为没有指定搜索路径。

我动这个念头不止一年,也不止一次,因为少有专研精神,每次的都不了了之,索性使用dcc32.exe时指定-U参数带上长上的搜索路径,使用的控件少还好,如果安装了JCL/JVCL这样的控件包,需要指定哪些路径还得慢慢摸索。

摸索到了搜索路径,修改dcc32.cfg文件,全局指定,也算是一劳永逸。

但是,还得当心重装系统文件丢失。

明摆在注册表的“Search Path”,我们就真拿她没办法么?follow me :)运行cmd.exe,切换到dos提示符下,输入一下命令串:C:/>reg queryHKCU/Software/Microsoft/Windows/CurrentVersion/Run看到了什么?对了!就是自启动程序列表。

既然可以使用命令取注册表的值,对于Delphi的Search Path应该也不在话下了。

C:/>reg query HKCU/Software/Borland/Delphi/7.0/Library /v "Search Path"这就是Delphi的搜索路径。

要应用到dcc32.exe中,可以写一批处理完成。

1.@echo off2.3.for /f "tokens=4" %%i in ('reg query HKCU\Software\Borl and\Delphi\7.0\Library /v "Search Path"') do set SearchPath=% %i4.5.dcc32.exe -B "D:/My Project/test.dpr" -U%SearchPath%6.7.这里的for ... in ... do ,是基本的dos命令,不明白的请google,这里的reg query,也是基本命令,不明白的请baidu。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1,影响整个系统里所有程序的修改
以ubuntu为例,在/etc/ld.so.conf.d目录下新增一个配置文件,名词任意,比如为mylib.conf:
lenky@Ubuntu:/etc/ld.so.conf.d$ sudo vi mylib.conf
[sudo] password for lenky:
lenky@Ubuntu:/etc/ld.so.conf.d$ cat mylib.conf
/home/lenky/lib
/usr/lib/otherapp/lib
指定了动态库的加载路径为/home/lenky/lib
执行ldconfig进行更新/etc/ld.so.cache:
lenky@Ubuntu:/etc/ld.so.conf.d$ sudo ldconfig
也就是说/etc/ld.so.cache里保存了系统在执行应用程序加载动态库的默认搜索路径。

动态库的搜索是有先后顺序的,先找到谁就使用谁。

2,影响特定环境下所有程序的修改
这利用的是LD_LIBRARY_PATH环境变量,在程序执行而加载动态库时,首先搜索的是
LD_LIBRARY_PATH指定的路径,然后再是/etc/ld.so.cache包含的系统默认搜索路径。

因此,如果主动指定某环境下的LD_LIBRARY_PATH环境变量,那么就能够影响该环境下的所有应用程序执行时加载动态库的搜索路径。

3,影响单个程序的修改
如果我只想指定某一个程序myexe的动态库搜索路径,比如我要把某个程序分发给用户,但又不知道用户电脑上是否安装了对应的依赖库或依赖库版本是否一致等,那么我干脆就提供这份库,并让我的程序myexe在执行时链接到我所提供的这份库,但又不能影响到用户电脑上的其他程序。

那么根据第2点的变通办法有:
a,创建一个脚本wrapper,在这个脚本里export LD_LIBRARY_PATH或setenv
LD_LIBRARY_PATH环境变量,然后执行程序。

b,创建一个程序wrapper,在这个程序export LD_LIBRARY_PATH环境变量,然后exec执行程序。

总之,也就是为执行这个程序myexe而创建一个单独的环境,并在这个环境里设置好
LD_LIBRARY_PATH。

可以实现既定目的,但会比较麻烦,一种更简单的方法是利用gcc的-
rpath参数。

有一段引用:
-rpath=dir
Add a directory to the runtime library search path. This is used
when linking an ELF executable with shared objects. All -rpath
arguments are concatenated and passed to the runtime linker, which
uses them to locate shared objects at runtime.
-L searchdir
–library-path=searchdir
Add path searchdir to the list of paths that ld will search for
archive libraries and ld control scripts.
简而言之,-L指定程序编译时的库搜索路径,而-rpath指定程序执行时的库搜索路径。

指定单个程序执行时的库搜索路径,利用-rpath即可,比如:
-Wl,-rpath,/path/to/foo -L/path/to/foo -lbaz
注意其中的-Wl,这表示它后面的参数是要传递给linker程序ld的。

通过这几个参数会让ld会在连接程序时,在程序里写上对应的elf动态段属性RPATH:
lenky@Ubuntu:~/test$ cat t.c
#include <stdio.h>
int main()
{
printf("\a");
}
lenky@Ubuntu:~/test$ gcc -o t -Wl,-rpath,/usr/lib,-rpath,/home/lenky/lib,-rpath,/opt t.c
lenky@Ubuntu:~/test$ readelf -a t | grep RPATH
0x0000000f (RPATH) Library rpath: [/usr/lib:/home/lenky/lib:/opt]
如果在编译时,库也在这几个特定路径,那么需要用-L来指定,以免编译时提示出错。

程序myexe执行时,就可以搜索RPATH内指定的路径了。

参考:
/questions/8482152/whats-the-difference-between-rpath-and-l
/questions/6562403/i-dont-understand-wl-rpath-wl
/wiki/Rpath
转载请保留地址:
/2013/10/16/%e4%bf%ae%e6%94%b9%e7%a8%8b%e5%ba%8f%e5%8a%a0%e 8%bd%bd%e5%8a%a8%e6%80%81%e5%ba%93%e6%90%9c%e5%af%bb%e8%b7%af%e5%b e%84%e7%9a%84%e4%b8%89%e7%a7%8d%e5%8f%af%e8%a1%8c%e6%96%b9%e6%b3%95
/或/?p=2354
备注:如无特殊说明,文章内容均出自Lenky个人的真实理解而并非存心妄自揣测来故意愚人耳目。

由于个人水平有限,虽力求内容正确无误,但仍然难免出错,请勿见怪,如果可以则请留言告之,并
欢迎来信讨论。

另外值得说明的是,Lenky的部分文章以及部分内容参考借鉴了网络上各位网友的热心分享,特别是一些带有完全参考的文章,其后附带的链接内容也许更直接、更丰富,而我只是做了
一下归纳&转述,在此也一并表示感谢。

关于本站的所有技术文章,欢迎转载,但请遵从CC创作共
享协议,而一些私人性质较强的心情随笔,建议不要转载。

法律:根据最新颁布的《信息网络传播权保护条例》,如果您认为本文章的任何内容侵犯了您的权利,请以Email或书面等方式告知,本站将及时删除相关内容或链接。

相关文档
最新文档