http://blog.sina.com.cn/s/blog_656681710100qzmy.html

工程里很多函数只是有声明,找不到实现的代码。因为那些实现代码已经编译成库所以看不见,我所看见的全是一堆头文件.

.o、.a、.so文件都是Linux下的程序函数库,即编译好的可以供其他程序使用的代码和数据。

优点:程序模块化,容易重新编译,方便升级。

分类:静态函数库(对应.a文件)、共享函数库(对应.so文件,类似于Windows的dll文件)、动态加载函数库(对应.o文件,相当于Windows里的.obj文件)

静态函数库

特点:实际上是简单的普通目标文件的集合,在程序执行前就加入到目标程序中。

优点:可以用以前某些程序兼容;描述简单;允许程序员把程序link起来而不用重新编译代码,节省了重新编译代码的时间(该优势目前已不明显);开发者可以对源代码保密;理论上使用ELF格式的静态库函数生成的代码可以比使用共享或动态函数库的程序运行速度快(大概1%-5%)

生成:使用ar程序(archiver的缩写)。ar rcs my_lib.a f1.o f2.o是把目标代码f1.o和f2.o加入到my_lib.a这个函数库文件中(如果my_lib.a不存在则创建)

使用:用gcc生成可执行代码时,使用-l参数指定要加入的库函数。也可以用ld命令的-l和-L参数。

共享函数库

共享函数库在可执行程序启动的时候加载,所有程序重新运行时都可自动加载共享函数库中的函数。.so文件感觉很复杂,光是命名规则就已经看得我很晕了~整理一下,共享库需要:soname、real name,另外编译的时候名字也有说法。依次解释下:

soname必须的格式:lib+函数库名+.so+版本号信息(但是记住,非常底层的C库函数都不是以lib开头命名的)。例子:/usr/lib/libreadline.so.3

real name:顾名思义是真正的名字啦,有主版本号和发行版本号。但是没找到实例……

编译器编译的时候需要的函数库的名字就是不包含版本号信息的soname,例如上面的例子把最后的.3去掉就可以了。

位置:共享函数库文件必须放在特定目录,对于开放源码来说,GNU标准建议所有的函数库文件都放在/usr/local/lib目录下,而且建议命令、可执行程序都放在/usr/local/bin目录下。不过这个只是习惯啦,可以改变,具体的位置信息可以看/etc/ld.so.conf里面的配置信息。当然,也可以修改这个文件,加入自己的一些特殊的路径要求。

创建:在网上找到了gcc方式和easyeclipse环境下两种创建方式。

gcc方式:

首先创建object文件,这个文件将加入通过gcc –fPIC 参数命令加入到共享函数库里面,标准格式:gcc -shared -Wl,-soname,your_soname -o library_name file_list library_list(说实话这个标准格式看起来好复杂,我找了个实例,但是好像和那个标准格式稍有不同:gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so)

在easyeclipse环境下生成.so文件:

1.选择新建工程,建立一个c++工程

2.在工程类型选项里选择 Shared Library,然后填入工程名字PXXX点击完成即可。

3.编写程序,然后编译就会在debug或者release里生成一个libPXXX.so文件,如果不要lib的起头标记点击project菜单的Properties选项,然后在弹出的界面的右边点击Build artifact页面,将Output prefix选项的内容清空即可。

4.如果是C++程序,注意在接口函数的前面加上extern "C"标记,在头文件加上如下标记:

#ifdef __cplusplus

#extern "C"{

#endif

头文件主体

#ifdef __cplusplus

}

#endif

如果不加以上标记,经过编译后,so里的函数名并非你编写程序时设定的函数名,在开发环境左侧的工程文件列表中点开debug项里的PXXX.o可以看到so文件里的函数名都是在你设定的函数名后面加了一个__Fi标记,比如你用的设定的函数名称是Func(), 而so里的函数名则为Func__Fi()或者其他的名称。

安装:拷贝共享库文件到指定的标准的目录,然后运行ldconfig。如果没有权限这样做,那么就只好通过修改环境变量来实现这些函数库的使用了。方法不再说了,很复杂。

查看:可以通过运行ldd来看某个程序使用的共享函数库。例如ldd /bin/ls。查看.so文件使用nm命令,如nm libXXX.so。(注意,nm对于静态的函数库和共享的函数库都起作用)

关于覆盖:如果想用自己的函数覆盖某个库中的一些函数,同时保留该库中其他的函数的话,可以在/etc/ld.so.preload中加入要替换的库(.o结尾的文件),这些preloading的库函数将有优先加载的权利。

关于更新:每次新增加动态加载的函数库、删除某个函数库或者修改某个函数库的路径时,都要重新运行ldconfig来更新/etc/ld.so.cache

Linux下的 .o、.a、.so文件的更多相关文章

  1. linux 下C语言编程库文件处理与Makefile编写

    做开发快3年了,在linux下编译安装软件算是家常便饭了.就拿gcc来说,都有不下10次了,可基本每次都会碰到些奇奇怪怪的问题.看来还是像vs.codeblocks这样的ide把人弄蠢了.便下定决心一 ...

  2. Linux下用rm删除的文件的恢复方法

    Linux下用rm删除的文件的恢复方法_Linux教程_Linux公社-Linux系统门户网站https://www.linuxidc.com/Linux/2008-08/14744.htm linu ...

  3. linux下查找指定后缀的文件

    1.linux下查找指定后缀的文件 例如查找当前目录下的所有后缀名时.c或.h的文件 find  .  -type f -regex  ".*\.\(c\|h\)"

  4. Linux下自动清除MySQL日志文件

    MySQL运行过程中会生成大量的日志文件,占用不少空间,修改my.cnf文件配置bin-log过期时间,在Linux下自动清除MySQL日志文件 [mysqld] expire-logs-days= ...

  5. Linux下的文件结构,及对应文件夹的作用

    Linux下的文件结构,及对应文件夹的作用 /bin 二进制可执行命令 /dev 设备特殊文件 /etc 系统管理和配置文件 /etc/rc.d 启动的配置文件和脚本 /home 用户主目录的基点,比 ...

  6. linux下添加用户并将文件夹授权给某一个用户

    ### linux下添加用户并将文件夹授权给某一个用户 背景:在做一个项目时,需要外包的前端人员调试测试环境的页面,但是又不能给他服务器的账号信息,就在服务器上新添加一个子账户,再给这个账户项目文件的 ...

  7. Linux下的命令,删除文件夹下的所有文件,而不删除文件夹本身

    Linux下的命令,删除文件夹下的所有文件,而不删除文件夹本身 rm -rf *

  8. linux 下用find命令查找文件,rm命令删除文件

    linux 下用find命令查找文件,rm命令删除文件. 删除指定目录下指定文件find 要查找的目录名 -name .svn |xargs rm -rf 删除指定名称的文件或文件夹: find -t ...

  9. [转帖]linux下使用 du查看某个文件或目录占用磁盘空间的大小

    linux下使用 du查看某个文件或目录占用磁盘空间的大小 du -ah --max-depth= 去年用过一次 后来忘记了.. 命令这个东西 熟能生巧.. https://www.cnblogs.c ...

  10. linux下shell脚本执行jar文件

    最近在搞一个shell脚本启动jar文件个关闭jar文件的东东.搞得我都蛋疼了.今天晚上终于弄好了 话说,小弟的linux只是刚入门,经过各方查资料终于搞定了.话不多说,下面开始上小弟写的shell脚 ...

随机推荐

  1. Ubuntu使用dpkg安装软件依赖问题解决 ubuntu-tweak ubuntu 16.04 LTS 系统清理

    Ubuntu使用dpkg安装软件依赖问题解决 这里以在ubuntu 16.04安装Ubuntu Tweak为例进行说明,通常安装包依赖问题都可以用这种方法解决: sudo apt-get instal ...

  2. 没事不要在for循环期间增减迭代序列的成员

    >>> arr=[4, 4, 9, 7, 7] >>> for i,a in enumerate(arr): arr.pop(i) print(i,a) 4 0 4 ...

  3. 使用Apache的ab进行压力测试

    概述 ab是apache自带的压力测试工具,当安装完apache的时候,就可以在bin下面找到ab然后进行apache 负载压力测试. 后台测试开发中,常用的压力测试服务,php一般选择xampp,下 ...

  4. 验证码程序Demo

    小伙伴都有这样的经历,册各种网站,总是输不对验证码,双十一那天狂买的小伙伴是不是对输入验证码有着不一样的感触呢,以前觉得验证码真是个麻烦鬼,一个不小心,一个眼拙,哎呦,没有输入正确,又是一阵子大眼瞪小 ...

  5. openfire环境搭建

    1.下载源代码:http://www.igniterealtime.org/downloads/source.jsp 2.把源代码解压出的openfire_src文件夹放至eclipse workpl ...

  6. 最简单的基于DirectShow的示例:视频播放器图形界面版

    ===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...

  7. Android的ScrollView和HorizontalScrollView-android学习之旅(四十一)

    HorizontalScrollView和ScrollView简介 ScrollView和HorizontalScrollView都继承于FrameLayout组件,两个都是容器,前者为里面的组件添加 ...

  8. 【一天一道LeetCode】#191. Number of 1 Bits

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Write a ...

  9. 【一天一道LeetCode】#217. Contains Duplicate

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...

  10. gradle编译出错:Execution failed for task ':app:compileTestDebugJava'.

    今天更新了android studio,从0.5.3升级到0.6.1版本,结果在IDE中编译时没有问题,但是在命令行时编译就会出现以下错误: :app:compileTestDebugJava FAI ...