一 静态链接库和动态链接库的区别
1 动态链接库有利于进程间资源共享
C语言的标准库是动态链接库,也就是说系统所有运行的程序共享着同一个C语言标准库的代码段。而静态库则不同,如果系统中多个程序都要调用静态库中的函数,则每个程序都要将这个库函数拷贝到自己的代码段中,这显然将占有更大的内存资源。
2 动态库使得一些程序升级简单。
用静态库,如果库发生变化,使用库的程序要重新编译,使用动态库,只要动态库提供给该程序的接口没有变化,只要用重新生成的动态库替换原来的就可以了。
3 对于动态库,可以真正做到链接载入完全由程序员在程序中控制。
程序员可以在编写程序的时候,可以明确的指明在什么时候在什么情况下,链接载入哪个动态链接库函数。
4 由于静态库在编译的时候,就将库函数载入到程序中去,而动态库函数必须在运行的时候才被载入,所以程序在执行的时候,用静态库速度更快些。
二 g++与gcc的区别
1 误区1与正解1
误区:gcc只能编译C代码,g++只能编译C++代码。
正解:gcc和g++都能编译C代码和C++代码。但编译时由所区别。
1.1 后缀为.c时,gcc把它当成C程序,而g++把它当前C++程序,后缀为.cpp时,两者都认为是C++程序。注意,虽然C++是C的超集,但是两者对语法的要求是有区别的,C++的语法规则会更加严谨。
1.2 编译阶段,g++会调用gcc,对于C++,两者是等价的;但是因为gcc命令不能自动和C++程序使用的库链接,所以通常用g++来完成链接,为了统一起见,干脆编译和链接统统用g++了,这就给人一种错觉,好像cpp程序只能用g++。
2 误区2与正解2
误区:gcc不会定义__cplusplus宏,而g++会
正解:这个宏只是标志着编译器会把代码按C还是C++语法来解释,如果后缀为.c,并且采用gcc编译器,则该宏就是未定义的,否则就是已定义的。
3 误区3与正解3
误区:编译只能用gcc,链接只能用g++
正解:编译可以用gcc/g++,而链接可以用g++或gcc -lstdc++。因为gcc命令不能自动和C++程序使用的库链接,所以通常用g++来完成链接。但在编译阶段,g++会自动调用gcc,二者等价。
4 误区4与正解
误区:extern "C"与gcc/g++有关系
正解:实际并没有关系,无论是gcc还是g++,用extern "C",都是以C的命名方式为symbol命令,否则,都以C++方式命名。
三 实战
1 me.h
extern "C" void CppPrintf (void);
2 me.cpp
#include<iostream>
#include"me.h"
using namespace std;
void CppPrintf(void){
cout<<"Hello"<<endl;
}
3 test.cpp
#include"me.h"
int main(){
CppPrintf();
return 0;
}
4 g++编译和查看
[root@localhost 0402]# g++ -S me.cpp
[root@localhost 0402]# cat me.s
......
.globl CppPrintf
.type CppPrintf, @function
5 gcc编译和查看
[root@localhost 0402]# gcc -S me.cpp
[root@localhost 0402]# cat me.s
......
.globl CppPrintf
.type CppPrintf, @function
从而得出结论,加了extern "C"后,CppPrintf这个函数用g++和gcc编译得到的函数命名是一样的,都是已C的命名方式命令。
6 将me.h的extern "C"去掉,用g++编译
[root@localhost 0402]# g++ -S me.cpp
[root@localhost 0402]# cat me.s
......
.globl _Z9CppPrintfv
.type _Z9CppPrintfv, @function
7 将me.h的extern "C"去掉,用gcc编译
[root@localhost 0402]# gcc -S me.cpp
[root@localhost 0402]# cat me.s
......
.globl _Z9CppPrintfv
.type _Z9CppPrintfv, @function
从而得出结论,去掉extern "C"后,CppPrintf这个函数用g++和gcc编译得到的函数命名是一样的,都是已C++的命名方式命令。可见extern "C"与采用gcc/g++并无关系。