g++生成和使用c++动态/静态链接库教程

c++库分为动态库与静态库,它们的区别是

使用动态库在编译时不将代码编译进程序,在程序里只有一个“指向”的位置,当需要相应功能的代码时会从动态库中调用,因此程序的运行需要动态库的支持。而使用静态库在编译时直接将相关功能代码编译进程序。所生成的程序能够独立运行,不依赖任何库。

动态库特点:

  • 生成的程序体积小
  • 能够实现一个动态库,多个程序共享使用。
  • 方便升级,只需要替换相应的动态库
  • 部署较难,容易发生几个应用程序使用同一个动态库发生版本冲突的问题。

静态库特点:

  • 生成的程序体积较大。
  • 对于多个程序都会用到的同一功能模块,如果采用静态编译将其编译到进每个程序中,就会造成不必要的代码重复。
  • 程序可以独立运行
  • 部署方便。

测试文件
模块a源文件,包含一个函数
moduleA.cpp

#include
void print_hello(){
	puts("hello!");
}

模块b源文件,包含一个类
moduleB.cpp

#include
#include"moduleB.h"
void cTest::function(){
	puts("this is cTest::function");
}

模块b的头文件(包含模块b中的类声明)
moduleB.h

class cTest{
	public:
	void function();
};

为了方便的使用这两个模块中的函数及类,为它们编写一个头文件
headerAB.h

//包含模块b的头文件,其中有模块b中的所有类声明
#include"moduleB.h"
void print_hello();

在main函数中,包含headerAB.h头文件,使用A,B模块中的函数及类。
main.cpp

#include"headerAB.h"
int main(){
	print_hello();
	cTest ct;
	ct.function();
	return 0;
}

编译环境:gcc-4.7.2


动态库

生成
方式一

g++ -fpic -shared 源文件名... -o 动态链接库名
  • -fpic (还可写成 -fPIC)选项的功能是,令 GCC 编译器生成动态链接库(多个目标文件的压缩包)时,表示各目标文件中函数、类等功能模块的地址使用相对地址,而非绝对地址。这样,无论将来链接库被加载到内存的什么位置,都可以正常使用;
  • -shared 选项用于生成动态链接库。
    在linux中,动态库后缀名是.so,而windows是.dll

g++生成和使用c++动态/静态链接库教程_第1张图片

方式二
生成目标文件

g++ -c -fpic 源文件名

生成动态库文件

g++ -shared 目标文件 -o 动态库名称

使用

g++ 源文件 库文件 -o 程序

在这里插入图片描述

若出现程序不能运行的问题,是因为找不到相应的动态库。需要将动态库文件拷贝到系统动态链接库文件夹,如windows的C:\Windows\System32文件夹,程序所在目录下,linux的/lib文件夹等。再运行程序即可


静态库

生成
生成目标文件

g++ -c 源文件

将目标文件生成静态库

ar rcs 静态库名称 目标文件

在linux中,静态库后缀名是.a,而windows是.lib。并且静态链接库的名称遵循特定规则
对于linux静态库名字格式为libxxx.a
对于windows静态库名字格式为libxxx.lib
其中xxx为起的静态库名字
g++生成和使用c++动态/静态链接库教程_第2张图片

使用
gcc默认进行动态编译,加入-static参数通知编译器进行静态编译
方式一

g++ -static 源文件 静态库文件 -o 程序

注意:静态库文件的顺序是在源文件之后,否则链接出错
在这里插入图片描述
方式二

g++ -static 源文件 -L 静态库所在目录 -l静态库名
  • -L 静态库所在目录
  • -l 静态链接库名字,后面不加空格。对于windows,-l链接的静态库名字带lib前缀,而linux不带。例如windows下,静态库名字为libmodules.lib,则参数为-llibmodules,而对于linux静态库名字为libmodules.a,参数为-lmodules

在这里插入图片描述


1.有时候想将程序功能给别人用,又不想公开源代码,就可以考虑将源文件编译成库文件,同时给别人提供相关的一组头文件即可。
例如上面测试的文件,编译成库后,只需要将生成的动态/静态库文件、headerAB.hmoduleB.h,交给对方就可以了
2.头文件(.h)只是对函数,变量,类的声明,而源文件(.cpp)才是模块真正实现的部分。头文件(.h)服务于源文件。
3.对项目进行构建时,有时候会在链接环节出错,与本文有关的原因可能是
包含了头文件,而没有编译相应的源文件或没有对应的库文件,导致链接找不到对应模块所致,如在vs项目文件中未包含源文件就不会进行编译,导致链接时出现错误。
也有可能是在头文件中进行了声明,而未在源文件中进行定义所致,本质上还是等于没有编译相对应的源文件。

参考文章:
GCC 编译 C(C++)静态链接库(gcc -L、gcc -l)和动态链接库(gcc -fPIC -shared)的创建和使用

你可能感兴趣的:(c++,c++,windows,开发语言)