第十三章 动态库与静态库

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

  静态库:  编译时候加载进目标文件内部。程序运行时不需要该库。命名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

   

原文地址:https://www.cnblogs.com/wolfrickwang/p/3193831.html