zoukankan      html  css  js  c++  java
  • linux静态库和动态库

      函数库是常用公共函数的集合,分为动态库和静态库。

      静态库:程序编译时被链接到目标文件中,程序运行时就不需要此函数库的存在。(不推荐,会重复链接库)

      动态库:程序编译时不链接到目标文件中,程序运行时才链接,所以需要函数库的存在。(推荐方式)

    1:静态库

      ./test/libhello/hello1.c

    #include <stdio.h>
    void print1()
    {
            printf("hello1****
    ");
    }

      ./test/libhello/hello2.c

    #include <stdio.h>
    void print2()
    {
            printf("hello2****
    ");
    }

      ./test/test.c

    #include<stdio.h>
    extern void print1();
    extern void print2();//避免 warning: implicit declaration of function "function name"
    int main(int argc,char **argv) { print1(); print2(); return 0; }

      1.1 将库文件(hello1.c,hello2.c)编译为.o文件

      ./test/libhello:

        gcc -c hello1.c hello2.c  --> hello1.o hello2.o

      -c : 只编译不链接

      1.2 用.o文件创建静态库

      静态库命名规则:lib+库名.a 比如要创建库hello,则静态库名字必须为libhello.a

      使用命令:

      ./test/libhello:

        ar -r libhello.a hello1.o hello2.o  --> libhello.a

      1.3 使用静态库

      test.c文件需要此静态库,只需要在编译test.c时gcc链接此静态库,静态库中的函数就会在目标文件中声明。

      ./test:

        gcc -o test test.c -L ./libhello -lhello  --> test

      -L:指定gcc在什么位置去链接hello库文件,不指定默认在/usr/lib中去找

      -l(库名):库名hello就对应了静态库libhello.a

      因为链接的是静态库,编译时库函数已经被链接进了目标文件test中,所以删除库文件libhello.a后test程序还是可以正常运行.

    2:动态库

      2.1 用.o文件生成动态库

      动态库命名规则:lib+库名.so 比如要创建库hello,则静态库名字必须为libhello.so

      使用命令:

      ./test/libhello:

        gcc -shared -fPCI -o libhello.so hello1.o hello2.o --> libhello.so

        cp libhello.so  /usr/lib (因为动态库是运行时才链接的,链接的默认位置是‘/usr/lib’,所以将.so拷贝至/usr/lib)

      2.2 使用动态库

      ./test:

        gcc -o test test.c -L ./libhello -lhello

      *:也可以在编译的时候指定链接的动态库的位置:gcc -o test test.c -L ./libhello/ -lhello -Wl,-rpath,./libhello/

      这样就不用把库文件拷贝到/usr/lib目录下,目标程序会自动去./libhello文件下去链接

      删除库文件libhello.so执行将出错:

        error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory

    3:总结

      1:当静态库和动态库同名时(libhello.a和libhello.so),默认使用的是动态库

      2:当一个库文件中有两个同名函数时,应用程序默认链接最前面哪个(比如hello1.o有print(),hello2.o有print(),在制作libhello.a时,ar -f libhello.a hello1.o hello2.o 这时会使用hello1.c中的print()函数)-->(在制作动态库时会提示命名冲突multiple definition of `print')

  • 相关阅读:
    一年来把自己从学.Net到用.Net,收集的资料共享出来B/s中的存储过程(二)
    收集的.Net文章(十五)ASP.NET 2.0 Caching For performance
    收集的.Net文章(十六)SQL Server日期计算
    P.V操作原语和信号量
    2004年2008年系分论文题目整理,考SA的可以看一下
    2010年个人总结
    MASM,NASM和AT&T汇编格式备注
    Unity Application Block 学习笔记之一使用配置文件
    Javascript 学习笔记之String类测试
    javascript学习笔记之Object类型测试
  • 原文地址:https://www.cnblogs.com/Flychown/p/6612030.html
Copyright © 2011-2022 走看看