C++程序编译之迷——隐藏源码,动态和静态链接库的秘密

左手编程,右手年华。大家好,我是一点,关注我,带你走入编程的世界。

公众号:一点sir,关注领取编程资料

前面我们提到了如果我们不希望把我们的源码提供出来,但是又想提供这个接口给调用者调用,那么这个该怎么做呢?

我们可以考虑用静态链接库或者动态链接库。

1、链接库

那么什么叫链接库呢?说白了,就是一个二进制文件,是通过特殊方式生成的一个二进制文件,在链接的时候,可以准确地生成可执行文件。

那么静态链接库和动态链接库有什么区别呢?

静态链接库在链接的时候程序会把静态链接库中的所有函数插入到你的可执行文件中,在这种链接方式下,函数的代码将从其所在地静态链接库中被拷贝到最终的可执行程序中。Linux平台一般都是.a结尾的文件,像libadd.a这样,window平台一般是.lib结尾的文件,像add.lib这样。

优点:运行速度比较快

缺点:可执行文件的会比较大

动态链接并没有说把库文件的代码插入到可执行文件中,而是在运行的时候链接库中的函数再加载到可执行文件中,也就是说运行的时候发现调用的函数是在动态库中,那么才去巴拉巴拉的加载。Linux平台一般都是.so结尾的文件,像libadd.so这样,window平台一般是.dll结尾的文件,像add.dll这样。所以很多时候你在window上安装软件,如果你到安装目录下查看,可能会看到很dll结尾的文件,而这些就是第三方的动态库。

优点:可执行文件的会比较小

缺点:运行速度比较慢

那么我们如何生成静态库和动态库,以下生成方法均是在Linux平台。

2、静态链接库

要生成静态链接库,首先生成.o文件

gcc -c add.cpp -o add.o

或者直接这样也可以,默认生成的也是.o文件

gcc -c add.cpp

生成静态链接库,静态库命名的规则lib+名字+.a

ar rcs libadd.a add.o

生成可执行文件

gcc main.c libadd.a -o maina

maina是利用静态库生成的可执行文件,这个实际上是比较简单的写法,是头文件、源文件、链接库都在同一目录的情况,如果是在不同的目录的话,就要这样

gcc main.cpp -Iinclude lib/libadd.a -o maina

简化成公式就是以下这样

gcc + 源文件 + -I头文件目录 + lib/libxxx.a + -o 可执行文件名

以上就是利用静态链接库生成可执行文件的方法,比较容易理解。ps:实际上还有另外一种方式生成静态库的,你知道是什么吗?

3、动态链接库

生成动态链接库,首先生成与位置无关的.o文件,-fPIC表示与位置无关

gcc -fPIC -c add.cpp -o libadd.o

ps:这边我也无法这个与位置无关到底是什么个意思,因为我用静态库那边的那个.o文件也可以生成动态库。

然后生成动态库

gcc -shared -o libadd.so libadd.o

组后生成可执行文件

gcc main.cpp libadd.so -o mainso

但是运行可执行文件的时候,可能会报以下错误:

vbnet 复制代码
./mainso: error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory

这个的意思是找不到动态链接库,解决办法是修改当前用户的.bash_profile文件,添加export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/yourpath,其中yourpath是你动态库存放的目录,比如我的是/app/process/alittle,最后执行source .bash_profile让环境变量生效。这里要记得一定要另开一个窗口执行,不然还是会这个错误。

以上就是静态库和动态库的内容,涉及到了一些编译过程的命令,所以后面我会和大家说下程序编译的相关过程。

相关推荐
无厘头三四十9 天前
现代编译器直接生成机器码的原理
编译原理
猪哥帅过吴彦祖12 天前
从源码到可执行文件:揭秘程序编译与执行的底层魔法
操作系统·编译原理·编译器
poemyang19 天前
性能优化之母:为什么说“方法内联”是编译器优化中最关键的一步棋?
java虚拟机·编译原理·即时编译器·方法内联
poemyang22 天前
new出来的对象,不一定在堆上?聊聊Java虚拟机的优化技术:逃逸分析
java虚拟机·编译原理·逃逸分析·即时编译器
前端缘梦23 天前
解锁webpack核心技能(三):从源代码到打包产物编译过程的原理指南
webpack·编译原理·前端工程化
poemyang23 天前
解锁硬件潜能:Java向量化计算,性能飙升W倍!
java虚拟机·编译原理·jit·向量化计算·smid
poemyang24 天前
Java编译器优化秘籍:字节码背后的IR魔法与常见技巧
java虚拟机·编译原理·ir·即时编译器
poemyang25 天前
“代码跑着跑着,就变快了?”——揭秘Java性能幕后引擎:即时编译器
java·java虚拟机·编译原理·jit·即时编译器
poemyang1 个月前
“同声传译”还是“全文翻译”?为何HotSpot虚拟机仍要保留解释器?
java·java虚拟机·aot·编译原理·解释执行
漂流瓶jz1 个月前
JavaScript语法树简介:AST/CST/词法/语法分析/ESTree/生成工具
前端·javascript·编译原理