zoukankan      html  css  js  c++  java
  • 第十三章 动态库与静态库

      工程中很多时候都会使用别人经过验证的库,或者第三方提供的库,现在很多工程中实际开发中是以库的形式对外发布,库主要分为静态库和动态库。

      静态库:  编译时候加载进目标文件内部。程序运行时不需要该库。命名libxxx.a

      动态库: 编译时链接至目标文件,只在目标文件内部指出连接地址。程序运行时加载动态库。 命名libxxx.so;

      

      实例讲解:

        本章实现 加法 、减法静态库,然后实现乘法、除法动态库。然后在main中调用。  现将每个文件代码列出如下:

        注意:源代码拷贝编译可能通不过,原因是有些括号是中文符号。改之则可。     

    //add.c
    
    int addNumint a, int b)
    {
         return (a+b);
    }
    //Sub.c
    
    int subNum(int a,int b)
    {
         return(a -b);
    }
    //mul.c
    
    int mulNum(int a ,int b)
    {
        return(a*b);
    }
    //div.c
    
    int  divNum(int a,int b)
    {
             return(a/b);
    }
    //main.c
    
    #include<stdio.h>
    #include<stdlib.h>
    #include"common.h"   //编译时候需要找到函数声明
    int main()
    {
           int a = 4;
           int b = 2;
    
           printf("a+b = %d
    ",addNum(a,b) );
           printf("a-b = %d
    ",subNum(a,b) );  
           printf("a*b = %d
    ",mulNum(a,b) );
           printf("a*b = %d
    ",divNum(a,b) );
    
    
    }
    //common.h
    extern int addNum (int a, int b);
    extern int subNum(int a,int b);
    extern int mulNum(int a ,int b);
    extern int divNum(int a,int b);

    (1) 静态库的生成

        1> 编译 

        $ gcc -c add.c  sub.c

      2> 打包 

           为了在可执行程序生成过程中,链接时正确找到库文件,静态库必须按照 lib[name].a 的规则命名。

           ar  命令  用于打包   

          -r  表示文件添加进文件包

          -s  创建链接库索引,该索引在程序链接时候使用  ranlib 命令也可以创建索引

         $  ar  -rs libaddsub.a   add.o  sub.o

         或

         $ ar r libstack.a stack.o push.o pop.o is_empty.o
         $ ranlib libstack.a

      

    (2)动态库的生成

      1> 编译

        组成动态库的目标文件和一般的目标文件有所不同,在编译时要加-fPIC选项  -f后面跟一些编译选项,PIC 是其中一种,表示生成位置无关代码。

          $ gcc -c -fPIC div.c  mul.c

      2> 生成动态库

         $ gcc div.o mul.o -shared -o libmuldiv.so  

          以上两步可以合在一起 $ gcc  div.c mul.c  -fPIC  -shared -o libmuldiv.so  

    (3)可执行文件的生成

      gcc 编译选项参数介绍

         -L  表示去哪里寻找 库文件    注: 即使在默认路径 也要指定路径 

       -I  表示去哪里寻找头文件

         -print-search-dirs  参数查看编译器默认会寻找的目录

          gcc main.c -L. -laddsub -lmuldiv -o main

          运行./main  提示找不到动态库libmuldiv.so 。

        这是因为 linux的可执行程序在执行的时候默认是先搜索/lib/usr/lib这两个目录,然后按照/etc/ld.so.conf里面的配置搜索绝对路径。同时,Linux也提供了环境变量LD_LIBRARY_PATH供用户选择使用,用户可以通过设定它来查找除默认路径之外的其他路径,如:LD_LIBRARY_PATH =/work/lib:$(LD_LIBRARY_PATH),并且LD_LIBRARY_PATH优先于系统默认路径之前查找。

      解决方法:

        第一种 :cp libmuldiv.so /usr/lib   程序安装时候一般会存放于目录

            第二种 :修改LD_LIBRARY_PATH   不推荐使用

        第三种 :修改/etc/ld.so.conf     程序调试时候建议使用 一次更改一直有效

        第四种 :创建一个连接到/usr/lib

    (4)ldd ,nm 命令

      使用ldd命令来查看执行文件依赖于哪些库

      要查看一个动态库包含哪些函数 使用nm 命令。

     (5) 本例makefile

      通过这个例子 大家可以学到如何在makefile中生成静态库或者动态库 。本例已经才ubuntu12.04 中测试验证过。

    #*****************************************************************************
    
    #
    
    # Author           :   wolfRickWang
    
    # Date             :   2013/7/17 星期三 13:27:22
    
    #
    
    #****************************************************************************/
    SHELL = /bin/sh
    CC = gcc
    AR = ar
    CFLAGS = -c 
    
    EXECUTABLE = main
    EXECUTLIB = libmuldiv.so
    EXECUTSLIB = libaddsub.a
    
    SOURCES = main.c
    
    SLIBSOURCES = add.c sub.c
    SLIBOBJECTS = $(SLIBSOURCES:.c=.o)
    
    LIBSOURCES = mul.c div.c
    
    $(EXECUTABLE): $(SOURCES) $(EXECUTLIB) $(EXECUTSLIB)
        $(CC) $(SOURCES) -L. -laddsub -lmuldiv -o $@
        
    $(EXECUTLIB) : $(LIBSOURCES)    
        $(CC) $(LIBSOURCES) -fPIC  -shared -o $@ 
    
    $(EXECUTSLIB):$(SLIBOBJECTS)
        $(AR) -rs $@ $(SLIBOBJECTS)
    
    %.o: %.c
        $(CC) $(CFLAGS) $< -o $@
    
    install:
        cp $(EXECUTLIB) /usr/lib
            
    clean:
        rm -f *.o $(EXECUTABLE) $(EXECUTLIB) $(EXECUTSLIB)
    
    .PHONY: clean install

       

  • 相关阅读:
    Vue和React组件diff更新影响范围对比
    ES6中import和CommonJS中require的区别
    MutationObserver监听DOM变化
    Mint UI中文官网
    为什么在浏览器不支持H265视频播放
    Google谷歌官网首页涂鸦记录
    windows键盘输入无效,键盘灯亮,打字不出字
    javascript实现跨域的方法汇总
    javascript中setInterval的用法
    浅谈Javascript数组的使用
  • 原文地址:https://www.cnblogs.com/wolfrickwang/p/3193831.html
Copyright © 2011-2022 走看看