c++ obj文件与exe文件的区别
编译:当前源代码编译成二进制目标文件(.obj文件)
链接(link):将生成的.obj文件与库文件.lib等文件链接,生成可执行文件(.exe文件)。
可以说.obj文件是.exe文件的前身;
1、obj里存的是编译后的代码跟数据,并且有名称,所以在连接时会出现未解决的外部符号一说。当连成exe后便不存在名称的概念了,只有地址。lib就是一堆obj的组合。
编译器会默认链接一些常用的库,其它的需要你自己指定。
2、目标文件,一般是程序编译后的【二进制文件】,再通过链接器和资源文件链接就成可执行文件了。OBJ只给出了程序的【相对地址】,而可执行文件是【绝对地址】。CPP对应的二进制代码格式obj,是未经重定位的!
3、编译C 程序会产生obj 文件和exe 文件,我们都知道exe 文件是可执行文件,但obj 文件是做什么用的呢?
查了下资料发现obj 文件和exe 文件都是二进制数据文件,其中obj 文件是COFF 格式,exe 文件时PE 格式。
那为什么不直接让 obj 文件作为可执行文件呢?
原来obj 文件的格式是跨平台 的,通过link 可以将obj 链接为所使用系统能够识别的格式,比如windows 系统中的exe 文件。
一个现代编译器的主要工作流程如下:
源程序(source code)→ 预处理器(preprocessor)→ 编译器(compiler)→ 汇编程序(assembler)→ 目标程序(object code)→ 连接器(链接器,Linker)→ 可执行程序(executables)
扩展资料
C++编译 (.obj, .lib, .dll, .exe的关系)
一、总体介绍:
c++程序在编译后,在目标路径下会生成多个文件:
Debug文件夹(*.exe,*.ilk,*.obj,*.pch,*.pdb,*.idb,*,pdb),*.cpp,*.dsp,*.ncb,*.plg
*.exe:是生成的可执行文件
*.ilk:当选定渐增型编译连接时,连接器自动生成ILK文件,记录连接信息
*.obj:是目标文件,源程序编译后的产物
*.pch:全称是PreCompiled Header,就是预先编译好的头文件
*.idb:文件保存的信息,使编译器在重新编译的时候只重编译最新改动过的函数和只对最新类定义改动过的源文件进行重编译,以提高编译速度
*.pdb:全称是Program DataBase,即程序数据库文件,用来记录调试信息
*.dsp:(全称是Developer Studio Project)也是一个配置文件
*.ncb:(全称No Compile Browser)的缩写,其中存放了供ClassView、WizardBar和Component Gallery使用的信息,由VC开发环境自动生成
*.plg:实际上是一个超文本文件,可以用Internet Explorer打开,记录了Build的过程
*.cpp:就是C++源代码文件.
二、具体介绍:
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的链接失败。
obj里存的是编译后的代码跟数据,并且有名称,所以在连接时会出现未解决的外部符号一说。当连成exe后便不存在名称的概念了,只有地址。lib就是一堆obj的组合。
2.理论上可以,但实际中通常用lib。
3.编译器会默认链接一些常用的库,其它的需要你自己指定。
附上lib和DLL的区别
(1)lib是编译时需要的,dll是运行时需要的。
如果要完成源代码的编译,有lib就够了。
如果也使动态连接的程序运行起来,有dll就够了。
在开发和调试阶段,当然最好都有。
(2)一般的动态库程序有lib文件和dll文件。
lib文件是必须在编译期就连接到应用程序中的,而dll文件是运行期才会被调用的。如果有dll文件,那么对应的lib文件一般是一些索引信息,具体的实现在dll文件中。
如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。静态编译的lib文件有好处:给用户安装时就不需要再挂动态库了。
但也有缺点,就是导致应用程序比较大,而且失去了动态库的灵活性,在版本升级时,同时要发布新的应用程序才行。
(3)在动态库的情况下,有两个文件,一个是引入库(.LIB)文件,一个是DLL文件。
引入库文件包含被DLL导出的函数的名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址。
这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。
从上面的说明可以看出,DLL和.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误。