C++编译原理
参考博客:https://www.cnblogs.com/kevinWu7/p/10163443.html
C/C++ 编译就是要将C/C++ 的代码映射到相应的机器码,以及讨论其中的内存管理模式,包括内存的分配,如何使用等等。整型,数组,指针等这些在内存中的实现机制。
C/C++的编译包括几个部分,分别是预处理,编译,汇编和链接。
1.预处理 (预处理文件C为".i", C++为".ii")
主要处理#include 和 #define
把#include包含的.h插入到对应位置,把#define替换为实际的字符串
-E 可以让预处理后不再编译
gcc -E hello.c -o hello.i
2.编译阶段 (将预处理文件编译成".s"文件)
检查代码规范,语法错误,并将代码翻译成汇编语言。
-S 选项只进行编译而不进行汇编,生成汇编代码。
gcc -S hello.i -o hello.s
3.汇编阶段 (汇编生成".o"文件)
将编译文件翻译成二进制机器指令文件.o
-c 告诉gcc进行汇编处理
gcc -c hello.s -o hello.o
4.链接,形成相应的动态和静态链接库。生成可以执行文件)
静态链接库就是将程序所需的所有程序直接拷贝到程序中来
程序运行时将所需的动态链接库加载到内存
1.dll , obj , lib 使用在windows平台下
.dll: 动态链接库,作为共享函数库的可执行文件
.obj: 对象文件,相当于源代码对应的二进制文件,未经重定位
.lib: 可理解为多个obj的集合,本质与.obj相同
2 .so .o .a使用在linux 平台下
.so : (share object)动态链接库,跟Windows平台类似
.o : 对象文件,相当于源代码对应的二进制文件
.a : 与.o类似,多个.o集合
静态联编 与 动态联编
联编就是决定将函数的调用映射到哪一个函数的过程
例:
class A class B
{ {
void func(){....} void func(){....}
} }
int main()
{
func(); //联编决定调用A.func 还是 B.func
}
静态联编:
是指联编工作是在程序编译连接阶段进行的,这种联编又称为早期联编;因为这种联编是在程序开始运行之前完成的;在程序编译阶段进行的这种联编又称静态束定;在编译时就解决了程序中的操作与执行该操作代码间的关系,确定这种关系又被称为束定;编译时束定又称为静态束定;
例:
#include <iostream>
using namespace std;
动态联编:
编译程序在编译阶段并不能确切地知道将要调用的函数,只有在程序执行时才能确定将要调用的函数,为此要确切地知道将要调用的函数,要求联编工作在程序运行时进行,这种在程序运行时进行的联编工作称为动态联编,或动态束定,又叫晚期联编;C++规定:动态联编是在虚函数的支持下实现的;
代码编译
-
动态库编译:
g++ function.c -I ./ -fPIC -shared -o libfunction.so
function.c 是我们要操作的目标源文件
因为function.c中有#include “function.h”,所以我们要在用 g++ 编译时给出function.h文件的位置。在 g++ 命令中,用-I选项标识.h文件的位置,此处我们的function.h与function.c在同一路径下,因此用命令** -I ./,其中./**表示当前所在路径。
-fPIC表示生成的是位置无关码(即使不加 fPIC 也可以生成 .so 文件,但是对于源文件有要求,例如因为不加 fPIC 编译的 so 必须要在加载到用户程序的地址空间时重定向所有表目,所以在它里面不能引用其它地方的代码)
-shared表示生成的是动态库(共享库)
-o用来指定输出文件的名字,-o libfunction.so表示生成文件名为libfunction.so
-
静态库
(一系列对象文件的集合)
g++ -c sayhello.cpp
g++ -c say.cpp
ar -r libsay.a sayhello.o say.o (该静态库包含sayhello.cpp,say.cpp两个cpp)
程序 ar 配合参数 -r 创建一个新库 libsay.a 并将命令行中列出的对象文件插入
采用这种方法,如果库不存在的话,参数 -r 将创建一个新的库,而如果库存在的话,将用新的模块替换原来的模块。
编译链接静态库
第一种:
通过指令 g++ -o main main.cpp libmix.a
第二种:
通过指令 g++ -o main main.cpp -L. -lmix
其中-L. 是链接静态库的路径,在此路径为当前目录,语法为-Lpath
-lmix 是静态库的名称标签,语法为-lxxx, 其中xxx省略了lib和.a后缀。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)