1, 在应用程序需要连接外部库的情况下,linux默认对库的连接是使用动态库,在找不到动态库的情况下再选择静态库。使用方式为:

gcc test.cpp -L. -ltestlib

如果当前目录有两个库libtestlib.so libtestlib.a 则肯定是连接libtestlib.so。如果要指定为连接静态库则使用:

gcc test.cpp -L. -static -ltestlib

使用静态库进行连接。

2, 当对动态库与静态库混合连接的时候,使用-static会导致所有的库都使用静态连接的方式。这时需要作用-Wl的方式:

gcc test.cpp -L. -Wl,-Bstatic -ltestlib  -Wl,-Bdynamic -ltestlib

3, 另外还要注意系统的运行库使用动态连接的方式,所以当动态库在静态库前面连接时,必须在命令行最后使用动态连接的命令才能正常连接

,如:

gcc test.cpp -L. -Wl,-Bdynamic -ltestlib -Wl,-Bstatic -ltestlib  -Wl,-Bdynamic


1、使用GCC创建和使用静态库

(1)gcc –o mylib.o –c mylib.c  //生成o文件
(2)ar -rcs libmylib.a mylib.o   //生成a文件
    -c create的意思
    -r replace的意思,表示当插入的模块名已经在库中存在,则替换同名的模块。
(3)cp libmylib.a /usr/lib/       //拷贝到默认目录
(4)编写程序使用库中的函数,需要包含相关的头文件,即可用下面的方式进行编译连接。
    gcc –o test test.c -L. -lmylib
    -L指定静态函数库的位置供查找,注意L后面还有'.',表示静态函数库在本目录下查找。
    -l则指定了静态函数库名,由于静态函数库的命名方式是lib***.a,其中的lib和.a忽略。

2、使用GCC创建和使用动态库

(1)gcc –fPIC –o mylib.o –c mylib.c
    gcc –shared –o libtt.so mylib.o
    -fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
    -shared 作用于链接阶段,实际传递给链接器ld,让其添加作为共享库所需要的额外描述信息,去除共享库所不需的信息。
(2)也可以直接使用下面一条命令:
    gcc –fPIC –shared –o libtt.so mylib.c
(3)将动态库拷贝到linux 的标准库中,usr/local/lib 或者/usr/lib 或者/lib,使用ldconfig命令加载
    cp libttt.so /usr/local/lib
(4) 编译src 程序使用动态库,隐式调用方法: 在编译调用库函数代码时指明动态库的位置及名字
    gcc –o test test.c  ./usr/lib/libttt.so
(5)编译src程序使用动态库,显示调用方法
     显式调用动态库需要四个函数的支持, 函数 dlopen 打开动态库, 函数 dlsym 获取动态库中对象基址, 函数 dlerror 获取显式动态库操作中的错误信息, 函数 doclose 关闭动态库.

#include <dlfcn.h> 
int main() 

                void *pHandle; 
                void (*pFunc)(); // 指向函数的指针 
                int *p; 
                pHandle = dlopen("./d1.so", RTLD_NOW); // 打开动态库 
                if(!pHandle){ 
                                printf("Can't find d1.so \n"); 
                                exit(1); 
                } 
                pFunc = (void (*)())dlsym(pHandle, "print"); // 获取库函数 print 的地址 
                if(pFunc) 
                                pFunc(); 
                else 
                                printf("Can't find function print\n"); 
                dlclose(pHandle); // 关闭动态库 
                return 0; 

gcc –o test test.c -lttt -L
    此时会到系统目录下去搜素libttt.so文件,具体搜索方法见下一节。

3、shell 搜索动态库路径位置的两种方法
    (1) 使用命令导入动态库的路径,命令如下:
    export LD_LIBRARY_PATH=dir (如/usr/local/lib)
    (2) 在/etc/ld.so.conf 文件中更增加一条,修改后用ldconfig 命令载入修改。

4、其他

(1)ldd命令可以查看一个可执行程序依赖的共享库,
    # ldd /bin/ln
    => /lib/libc.so.6 (0×40021000)/lib/ld-linux.so.2
    => /lib/ld- linux.so.2 (0×40000000)
    可以看到ln命令依赖于libc库和ld-linux库

(2)看动态库包含哪些定义用:
     nm -D lib*.so

(3)当生成动态库时,源文件又引用其他静态库,需要一起写。这时源文件里面不用用extern f();,这样就不能引入静态库。需要直接#include 头文件。

比如,gcc -fexceptions -O2 -o hello.node ./build/Release/obj.target/hello/hello.o ./libpanda.a /usr/local/lib/libnfc.a  -shared -fPIC

参考:

gcc生成静态库和动态库: http://blog.csdn.net/ast_224/article/details/3988244

动态库(.so)链接静态库(.a)的情况总结

 http://www.cnblogs.com/nobugtodebug/archive/2012/11/07/e6cd72c67b3dd843f40d7ce919f7336a.html

http://www.cppblog.com/deane/archive/2014/05/23/165216.html

linux动态库与静态库混合连接的更多相关文章

  1. gcc 混合连接动态库和静态库

    当对动态库与静态库混合连接的时候,使用-static会导致所有的库都使用静态连接的方式.这时需要作用-Wl的方式 gcc test.cpp -L. -Wl,-Bstatic -ltestlib  -W ...

  2. Linux中的动态库和静态库(.a/.la/.so/.o)

    Linux中的动态库和静态库(.a/.la/.so/.o) Linux中的动态库和静态库(.a/.la/.so/.o) C/C++程序编译的过程 .o文件(目标文件) 创建atoi.o 使用atoi. ...

  3. Linux系统中“动态库”和“静态库”那点事儿 /etc/ld.so.conf 动态库的后缀为*.so 静态库的后缀为 libxxx.a ldconfig 目录名

    Linux系统中“动态库”和“静态库”那点事儿 /etc/ld.so.conf  动态库的后缀为*.so  静态库的后缀为 libxxx.a   ldconfig   目录名 转载自:http://b ...

  4. Linux系统中“动态库”和“静态库”那点事儿【转】

    转自:http://blog.chinaunix.net/uid-23069658-id-3142046.html 今天我们主要来说说Linux系统下基于动态库(.so)和静态(.a)的程序那些猫腻. ...

  5. linux中C的静态库和动态库分析

    从开始学C语言写第一个"hello world"历程到现在,我依然困惑于到底这个程序完整的执行流程是什么样的.不过,现在我正在尝试一点一点的揭开它的面纱.现在,我尝试分析linux ...

  6. 技巧:Linux 动态库与静态库制作及使用详解

    技巧:Linux 动态库与静态库制作及使用详解 标准库的三种连接方式及静态库制作与使用方法 Linux 应用开发通常要考虑三个问题,即:1)在 Linux 应用程序开发过程中遇到过标准库链接在不同 L ...

  7. Linux系统中“动态库”和“静态库”那点事儿

    摘自http://blog.chinaunix.net/uid-23069658-id-3142046.html 今天我们主要来说说Linux系统下基于动态库(.so)和静态(.a)的程序那些猫腻.在 ...

  8. Linux的动态库与静态库

    1.动态库与静态库简介 在实际的软件开发中,为了方便使用一些被重复调用的公共代码,我们经常将这些公共的函数编译成动态库或静态库.我们知道程序一般要经过预处理.编译.汇编和链接这几个步骤才能变成可执行的 ...

  9. Linux环境编译动态库和静态库总结

    对Linux环境动态库和静态库的一些基础知识做一些总结, 首先总结静态库的编译步骤. 1 先基于.cpp或者.c文件生成对应的.o文件 2将几个.o文件 使用ar -cr命令 生成libname.a文 ...

随机推荐

  1. System.Data.SqlClient.SqlException:“对象名 'customer' 无效。"

    连接数据库出错, 错误原因:表名错误.

  2. 【调试技巧】 Fiddler高级用法之url映射请求

    问题场景: 已发布线上APP出现接口错误,如何测试线上APP访问本地请求? 已发布线上H5页面,静态资源或js调试,如何映射本地js? 一般解决方案: 猜测(一般明显问题). 找到原发布包,修改请求资 ...

  3. ssh实现办公室电脑连接家中的电脑

    友情提示:如果您不知道您家路由器管理页面的密码,请您忽略此文. 问题背景: 家中有台笔记本电脑,它是通过家中的路由器与外界联网的,这时,我想通过ssh服务让公司的电脑能连上我家中的笔记本. 可以画个图 ...

  4. webpack笔记

    打包 img src src 必须以 点(.) 开始,才能被打包. 如: ./img/logo.png ../img/logo.png 使用 process a.js window.Base_Url ...

  5. 编写脚本自动部署反向代理、web、nfs

    服务器端 #!/bin/bash function nginx_install(){ if [[ -f /usr/sbin/nginx ]]; then echo 'Nginx has been in ...

  6. mysql操作命令梳理(4)-grant授权和revoke回收权限

    在mysql维护工作中,做好权限管理是一个很重要的环节.下面对mysql权限操作进行梳理: mysql的权限命令是grant,权限撤销的命令时revoke:grant授权格式:grant 权限列表 o ...

  7. git 配置别名

    对于常用的git的命令,可以通过配置别名的方式,提高工作效率. $ git config --global alias.co checkout //执行git co 相当于git checkout $ ...

  8. python基础学习笔记(五)

    字符串基本操作 所有标准的序列操作(索引.分片.乘法.判断成员资格.求长度.取最小值和最大值)对字符串同样适用,前面已经讲述的这些操作.但是,请注意字符串都是不可变的. 字符串的方法: 字符串从str ...

  9. 发布阶段 github和360移动助手及总结

    经过一系列的冲刺和加工 最激动人心的无非在发布平台上公布上自己辛苦奋斗了一个周期的产品,这个时候的我们就像Iphone 6发布会上得CEO,为自己的产品完美画上了研发的句号. 接下来的日子就是准备ve ...

  10. 推广App篇

    推广App篇 团队github地址:https://github.com/ouqifeng/EasyGoOperation.git 在完成该项目工程后,我们开始寻找合适的方法推广我们的软件. 经过一番 ...