您的位置:首页 > 运维架构 > Linux

linux c调用链接库

2011-12-02 11:11 85 查看
转自:http://shezzdd.blog.163.com/blog/static/39008634200872995923765/

一。静态链接库的调用(.a)

调用静态链接库时,只要把需要的静态链接库放在源文件或者.o文件后面,即可编译,连接,或运行,不再需要其他的处理

也可以用-L -l选项指定静态链接库的目录和名称(-l的使用规则为:-lX,则使用的库为libX.a),一般他们是成对出现的。另外重要的一点是一般不-L -l选项放在编译命令的最后。否则会出错。

二. 动态链接库的调用(.so)

利用动态链接库运行程序的时候,在编译程序时需要加入-L -l 选项,表示动态链接库的目录和那一个库。

一旦程序被连接,要使用共享库,就必须在运行的时候能够找到共享库的位置。默认情况下只在公用库目录(如/lib,/usr/lib等)中查找,所以找不到你自己编写的动态库。 <br>
linux的excutable在执行的时候缺省是先搜索/lib和/usr/lib这两个目录,然后按照ld.so.conf里面的配置搜索绝
对路径,linux缺省是不会在当前目录搜索动态库的。linux的动态库搜索顺序虽然可以说成是比较严谨,但是相对来说也比较呆板,有时候会造成不便。
其实,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也可以,但只支持绝对路径

以下为转载的内容,写的比较好:


当link library的时候,有两种link的方式:静态link和动态link。
一个Archieve其实就是多个object文件的压缩集合。当你link的时候给编译器指定的是一个Archieve,编译器会从中解压出需要的object文件并进行link。(静态link)
archieve可以用ar cr命令来创建(ar cr libtest.a test1.o test2.o)
注意编译器会在第一次碰到Archieve的时候开始从中解压并提取需要的信息,这里所谓的“需要的信息”是所有已经使用但还没有定义的符号。因此在命令行中指定Archieve的顺序非常之重要,通常放在最后。假设libtest.a中定义了函数f(),main.o中用到了函数f,则

gcc -o app -ltest app.o会失败,因为在-ltest的时候编译器并没有发现有任何程序调用了函数f(),它也就不会把f()的信息从libtest.a里面提取出来并link

o gcc -o app app.o -ltest则会编译成功。
一个shared library和archieve对应。不同的是,sharedlibrary不是object文件的集合,而是一个单一的object文件。因此当sharedlibrary被link的时候,编译器不会像对待archieve那样只link其中需要的部分,而是link所有的内容。(动态link)

要创建一个shared library,则你必须在用gcc编译object文件的时候,指定-fPICoption。PIC的意思是Position-IndependentCode,即该代码执行的效果和它被load的地址无关。当然,绝大多数情况下的时候都是无关的,如果你不是很明白我在说什么,尽管忽略它,只需要记住加上-fPIC来构建一个给shared library用的object文件就可以了。
然后我们就可以用gcc加上-shared option来构造一个shared library了:gcc -shared -fPIC -o libtest.so test1.o test2.o。shared library的后缀名是so。
编译可执行文件的时候link sharedlibrary的格式和archieve一样。因此在link的时候,编译器会先找每一个library的目录(-L指定的优先找),如果找到了shared library或者archieve中的一个,则link之。如果两个都在同一个目录找到了,除非你给gcc指定了-staticoption,否则编译器默认link shared library。
ldd命令会显示一个可执行文件上link的shared library
环境变量LD_LIBRARY_PATH用来指明library的路径
编译C文件的时候,gcc会自动link标准C库,libc。当编译C++文件的时候,g++会自动link标准C++库,libstdc++。如果需要使用到一些数学函数,例如正弦函数,需要link libm
library会出现依赖现象,即一个library调用了另一个library中定义的函数,这很容易理解。这种情况下,当动态link的时候,只需要指定程序直接依赖的library就可以了;但静态link的时候,需要指定程序所有依赖的library,包括传递依赖的library。
除了在编译的时候link,在程序中也可以动态link,使用dlopen(load library),dlsym(查找library中的function)和dlclose(unload library)
如果使用C++来编写shared library,应该把需要export的函数声明为extern “c”,否则C++会把函数重命名为你看不懂,linker也看不懂的东西。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: