博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
静态函数库的制作和使用
阅读量:5238 次
发布时间:2019-06-14

本文共 3756 字,大约阅读时间需要 12 分钟。

C语言的函数库是多组经过验证的常用函数的集合,编写C语言程序时使用库函数,既可以提高程序运行效率,又可以提高编程质量,使用方法如#include 和#include。

根据使用库函数时,函数库加载时机的差异,将函数库分为静态函数库和动态函数库,具体差异是:C语言程序如果使用静态函数库的函数,那么整个函数库的代码都会和C语言程序一起编译成可执行代码,程序的体积会膨胀;如果使用动态函数库的函数,则C语言程序只会和函数库文件名以及函数名一起编译成可执行代码(不编译函数代码),运行时去查找函数库文件和函数体,程序的体积基本不变。

简单概括就是,静态函数库是“以空间换时间”,增加程序体积,减少运行时间,如果静态函数库发生改变,则整个程序必须重新编译,因为函数库被整合到了最终可执行代码中;动态函数库则是“以时间换空间”,增加运行时间,减少程序体积,如果动态函数库发生改变,程序无须重新编译,因为函数库没有整合到最终可执行代码中。

Linux中静态函数库表示为”libxxx.a”,windows中后缀名为”.lib”;Linux中动态函数库表示为”libxxx.so”,windows中后缀名为”.dll”。函数库中存放内容包括:(1)函数名称,(2)函数目标代码(二进制),(3)重定位信息(链接需要)等。

 

1 静态函数库的制作和使用

   静态函数库的制作步骤可以用下图来描述,具体包括

(1)  编写函数的.c文件(例如add.c、sub.c、mul.c和div.c)

(2)  编写Makefile,然后make,实现函数的编译和归档入库

函数的编译:使用gcc –c 只编译不链接函数.c文件,分别生成函数的目标文件(例如add.o、sub.o、mul.o和div.o)。

函数的归档入库:使用ar -rc libxxx.a  $(objects) 将目标文件归档入库。

(3)  编写头文件(例如ku.h),声明静态函数库中的所有函数,目的是kumain.c函数#include头文件后,可以调用相应的函数,至此,完成函数库的制作。

 

1.1 静态函数库的制作示例

      示例的内容是建立静态函数库libstatic.a,库中包括addsubmuldiv函数,然后在kumain.c函数中引用这4个函数,实现两个整数的加减乘除,整个文件的结构是

 

      所有代码见:http://files.cnblogs.com/files/hfxin2001-eric-daddy/ku.rar

(1)  编写函数的.c文件

      编写4个函数文件add.csub.cmul.cdiv.c

//  add.c float add(int a, int b){ return (a+b);}

 

// sub.c float sub(int a, int b){return (a-b);}

 

//  mul.c float mul(int a, int b){return (a*b);}

 

//  div.c float div(int a, int b){return (a/b);}

 

(2)  编写头文件

//  ku.h float add(int a, int b);float sub(int a, int b);float mul(int a, int b);float div(int a, int b);

(3)  编写Makefile

###  Makefile for static func lib objects = add.o sub.o mul.o div.o libstatic.a : $(objects)     ar -rc libstatic.a $(objects)add.o : add.c    gcc -c add.csub.o : sub.c    gcc -c sub.cmul.o : mul.c    gcc -c mul.cdiv.o : div.c    gcc -c div.cclean :     rm libstatic.a $(objects)

(4)  使用make编译.c文件,生成.o文件,归档.o文件到函数库libstatic.a中,完成静态函数库的制作。

 

1.2 静态函数库的使用

(1)    编写kumain.c,调用libstatic.a中的add、sub、mul和div函数

//  kumain.c #include 
#include "ku.h" int main (void){int a,b;a = 10;b = 3;printf("a = %d.\nb = %d.\n",a,b);printf("static a+b = %f.\n",add(a,b));printf("static a-b = %f.\n",sub(a,b));printf("static a*b = %f.\n",mul(a,b));printf("static a/b = %f.\n",div(a,b));return 0;}

(2)    使用gcc kumain.c –o kumain.o –L ./ku2 –lstatic 编译kumain.c文件,运行./kumain.o查看运行结果,成功。

 

1.3  使用nm查看kumain.o中的符号信息

      nm命令是列出.o文件,.a文件和.so文件中的符号信息,如符号的值,符号类型及符号名称等。符号通常指定义出的函数,全局变量等。

使用 nm libstatic.a查看符号信息,得到

使用nm kumain.o >label.text查看kumain.o中的符号信息,得到

080484f9 T add0804a020 B __bss_start0804a020 b completed.65910804a018 D __data_start0804a018 W data_start08048370 t deregister_tm_clones0804853c T div080483e0 t __do_global_dtors_aux08049f0c t __do_global_dtors_aux_fini_array_entry0804a01c D __dso_handle08049f14 d _DYNAMIC0804a020 D _edata0804a024 B _end080485c4 T _fini080485d8 R _fp_hw08048400 t frame_dummy08049f08 t __frame_dummy_init_array_entry080487b8 r __FRAME_END__0804a000 d _GLOBAL_OFFSET_TABLE_         w __gmon_start__080482cc T _init08049f0c t __init_array_end08049f08 t __init_array_start080485dc R _IO_stdin_used         w _ITM_deregisterTMCloneTable         w _ITM_registerTMCloneTable08049f10 d __JCR_END__08049f10 d __JCR_LIST__         w _Jv_RegisterClasses080485c0 T __libc_csu_fini08048550 T __libc_csu_init         U __libc_start_main@@GLIBC_2.00804842d T main08048527 T mul         U printf@@GLIBC_2.0080483a0 t register_tm_clones08048330 T _start0804850f T sub0804a020 D __TMC_END__08048360 T __x86.get_pc_thunk.bx

 

1.4 nm命令简介

nm [option(s)]  [file(s)]

有用的options:

  • -A 在每个符号信息的前面打印所在对象文件名称;
  • -C 输出demangle过了的符号名称;
  • -D 打印动态符号;
  • -l 使用对象文件中的调试信息打印出所在源文件及行号;
  • -n 按照地址/符号值来排序;
  • -u 打印出那些未定义的符号;

常见的符号类型

  • A 该符号的值在今后的链接中将不再改变;
  • B 该符号放在BSS段中,通常是那些未初始化的全局变量;
  • D 该符号放在普通的数据段中,通常是那些已经初始化的全局变量;
  • T 该符号放在代码段中,通常是那些全局非静态函数;
  • U 该符号未定义过,需要自其他对象文件中链接进来;
  • W 未明确指定的弱链接符号;同链接的其他对象文件中有它的定义就用上,否则就用一个系统特别指定的默认值。

 

转载于:https://www.cnblogs.com/hfxin2001-eric-daddy/p/5809010.html

你可能感兴趣的文章
python的多行注释
查看>>
连接Oracle需要jar包和javadoc文档的下载
查看>>
UVA 10976 - Fractions Again?!
查看>>
Dreamweaver cc新版本css单行显示
查看>>
【android】安卓的权限提示及版本相关
查看>>
JavaScript可否多线程? 深入理解JavaScript定时机制
查看>>
IOS基础学习
查看>>
PHP 导出 Excell
查看>>
Java基础教程——网络基础知识
查看>>
Kruskal基础最小生成树
查看>>
ubuntu 14.04 安装搜狗拼音输入法
查看>>
浅谈算法和数据结构: 一 栈和队列
查看>>
Java内部类详解
查看>>
【hdu 1429】胜利大逃亡(续)
查看>>
图论-次短路求法
查看>>
What's New for Visual C# 6.0
查看>>
ExtJs学习笔记之ComboBox组件
查看>>
关于收费软件
查看>>
getopt_long
查看>>
TensorFlow MNIST CNN 代码
查看>>