关于整个编译过程和库文件的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于整个编译过程和库文件的问题相关的知识,希望对你有一定的参考价值。

论述1
在C中
编译器单独编译(Compile)每个源文件(.c)生成相应的目标文件(.obj)
链接器链接(Link)各个目标文件(.obj)和资源文件(.res)生成可执行文件(.exe)
其中,obj是Complie的产物,同时也是Link的对象,而exe是Link的产物

问题1(可多选)
静态库文件(lib)是
A、Compile的产物
B、Link的对象
C、Link的产物
D、其他(请详细说明)

论述2
link成功会生成可执行文件(exe),此时运行程序(Execute Program)就相当于运行exe文件

问题2(可多选)
动态库文件(dll)是
A、Link的产物
B、Execute时链接的对象
C、其他(请详细说明)

问题3
一个程序从编译、链接、生成可执行文件到运行它,是不是系统自动并且一定会生成lib和dll?
如果不是,如何手动去生成lib和dll?

问题1:
BD
D:通过目标文件归档程序(VC++中是lib.exe)和其它方式(例如由dll文件生成lib文件)得到的产物 。
问题2:
AB
问题3:
不一定。首先,一个完整的程序的全编译过程可以仅依赖于现有的库文件,且不在这个程序的编译过程生成库文件。其次,库文件的格式不一定是lib和dll文件。至于手动生成lib和dll,这个和使用的工具相关。例如VC++的命令行可以用编译程序cl.exe编译源文件为目标文件,用归档程序lib.exe连接obj和lib文件生成静态库,用链接程序link.exe链接目标文件和资源文件生成exe和dll。
====
[原创回答团]

参考资料:原创 + Google确认

参考技术A 1 ABD, 会加载到生成的可执行文件中
2 ABC, 不会加载到生成的可执行文件中
3 不是. 编译器会有对应的选项去帮助你生成所需的文件, 比如
gcc a.c -shared -o a.dll -Wl,--output-def,a.def,--out-implib,liba.a
就可以给你生成个.dll

Java代码编译和执行的整个过程

Java代码的编译和执行的整个过程大概是:开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件),再然后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器码执行。

(1)Java代码编译是由Java源码编译器来完成,也就是Java代码到JVM字节码(.class文件)的过程。 流程图如下所示:

技术分享图片

(2)Java字节码的执行是由JVM执行引擎来完成,流程图如下所示:

技术分享图片

 

Java代码编译和执行的整个过程包含了以下三个重要的机制:

·Java源码编译机制

·类加载机制

·类执行机制

 

(1)Java源码编译机制

Java 源码编译由以下三个过程组成:

①分析和输入到符号表

②注解处理

③语义分析和生成class文件

流程图如下所示:

技术分享图片

最后生成的class文件由以下部分组成:

①结构信息:包括class文件格式版本号及各部分的数量与大小的信息

②元数据:对应于Java源码中声明与常量的信息。包含类/继承的超类/实现的接口的声明信息、域与方法声明信息和常量池

③方法信息:对应Java源码中语句和表达式对应的信息。包含字节码、异常处理器表、求值栈与局部变量区大小、求值栈的类型记录、调试符号信息

(2)类加载机制
JVM的类加载是通过ClassLoader及其子类来完成的,类的层次关系和加载顺序可以由下图来描述:

技术分享图片

①Bootstrap ClassLoader

负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类

②Extension ClassLoader

负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包

③App ClassLoader

负责记载classpath中指定的jar包及目录中class

④Custom ClassLoader

属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader

 

加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只所有ClassLoader加载一次。而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。

(3)类执行机制

JVM是基于堆栈的虚拟机。JVM为每个新创建的线程都分配一个堆栈.也就是说,对于一个Java程序来说,它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。

JVM执行class字节码,线程创建后,都会产生程序计数器(PC)和栈(Stack),程序计数器存放下一条要执行的指令在方法内的偏移量,栈中存放一个个栈帧,每个栈帧对应着每个方法的每次调用,而栈帧又是有局部变量区和操作数栈两部分组成,局部变量区用于存放方法中的局部变量和参数,操作数栈中用于存放方法执行过程中产生的中间结果。栈的结构如下图所示:

技术分享图片


以上是关于关于整个编译过程和库文件的问题的主要内容,如果未能解决你的问题,请参考以下文章

Java代码编译和执行的整个过程

Java代码编译和执行的整个过程

Java代码编译和执行的整个过程

java --代码编译和执行的整个过程

关于 js 的作用域的对话过程的理解

C/C++程序编译过程详解