linux c调用链接库

来源:互联网 发布:哪个旅行团比较好知乎 编辑:程序博客网 时间:2024/05/21 13:28
转自: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_PATHPS:修改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也看不懂的东西。

原创粉丝点击