Linux中的源文件、目标文件、库文件

在说明Linux的.a、.so和.o文件关系之前,先来看看windows下obj,lib,dll,exe的关系

 

windows下obj,lib,dll,exe的关系

    lib是和dll对应的。lib是静态链接库的库文件,dll是动态链接库的库文件。 
    所谓静态就是link的时候把里面需要的东西抽取出来安排到你的exe文件中,以后运行你的exe的时候不再需要lib。
    所谓动态就是exe运行的时候依赖于dll里面提供的功能,没有这个dll,你的exe无法运行。 
    
    lib,dll,exe都算是最终的目标文件,是最终产物。而c/c++属于源代码。源代码和最终目标文件中过渡的就是中间代码obj,实际上之所以需要中间代码,是你不可能一次得到目标文件。比如说一个exe需要很多的cpp文件生成。而编译器一次只能编译一个cpp文件。这样编译器编译好一个cpp以后会将其编译成obj,当所有必须要的cpp都编译成obj以后,再统一link成所需要的exe,应该说缺少任意一个obj都会导致exe的链接失败。
    
    1.obj里存的是编译后的代码跟数据,并且有名称,所以在连接时有时会出现未解决的外部符号的问题。当连成exe后便不存在名称的概念了,只有地址。lib就是一堆obj的组合。
    2.理论上可以连接obj文件来引用其他工程(可以认为一个obj文件等价于编译生成它的cpp文件,可以引用obj来替换cpp,也可以添加cpp来替换obj ),但实际中通常用lib来实现工程间相互引用。
    3.编译器会默认链接一些常用的库,其它的需要你自己指定。
    
lib和DLL的区别

    (1)lib是编译时需要的,dll是运行时需要的。如果要完成源代码的编译,有lib就够了。如果也使动态连接的程序运行起来,有dll就够了。在开发和调试阶段,当然最好都有。
    (2) 一般的动态库程序有lib文件和dll文件。lib文件是必须在编译期就连接到应用程序中的,而dll文件是运行期才会被调用的。如果有dll文件,那么对应的lib文件一般是一些索引信息,具体的实现在dll文件中。如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。 静态编译的lib文件有好处:给用户安装时就不需要再挂动态库了。但也有缺点,就是导致应用程序比较大,而且失去了动态库的灵活性,在版本升级时,同时要发布新的应用程序才行。
    (3)在动态库的情况下,有两个文件,一个是引入库(.LIB)文件(实际上也算是一个静态库,只是在链接时只能把函数在DLL的入口链接到exe中,而不像真正静态链接库那样将函数体真正链接到exe中 ,通过lib进行的动态链接实际上也使用了静态链接来实现 ),一个是DLL文件,引入库文件包含被DLL导出的函数的名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。从上面的说明可以看出,DLL和.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误。

DLL内的函数分为两种: 
    (1)DLL导出函数,可供应用程序调用;
    (2)DLL内部函数,只能在DLL程序使用,应用程序无法调用它们

创建静态链接库和创建动态链接库

    VC6中创建[Win32 Dynamic-Link Library]工程便可以创建出一个空的DLL工程.

    VC6中创建[Win32 Static Library]工程便可以创建出一个空的LIB工程(静态链接库工程,仅生成一个lib文件).

添加lib文件的常用办法有二个: 
    1、把*.lib放在VC的Lib目录中 
    2、修改project setting的Link->Input中的Addtional library path,加入你的目录dll:是可实际运行的二进制代码,有定位代码的!

    3、也可以在object/library中直接写上lib文件路径.(这里实际上是可以写上任意obj文件或者lib文件的).

 

 

 

linux .o,.a,.so

        .o,是目标文件,相当于windows中的.obj文件 

  .so 为共享库,是shared object,用于动态连接的,相当于windows下的dll 

  .a为静态库,是好多个.o合在一起,用于静态连接 

 

静态函数库
特点:实际上是简单的普通目标文件的集合,在程序执行前就加入到目标程序中。
优点:可以用以前某些程序兼容;描述简单;允许程序员把程序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里面的配置信息。当然,也可以修改这个文件,加入自己的一些特殊的路径要求。

猜你喜欢

转载自blog.csdn.net/qq_36689800/article/details/78151395