关于linux下GCC生成共享库(动态链接库)的探究

下面列出了我在对共享库(动态链接库)编写以及使用时遇到的几个简单问题进行探究和解答:

参考文档:http://www.cnblogs.com/likwo/archive/2012/05/09/2492225.html

1.静态库、动态链接库、共享库有什么区别?

  静态库(windows下为.lib,linux下为.a)是在程序编写前就编译到目标程序中了,而动态链接库(windows下为.dll)可以在程序执行的任何时候被动态加载。共享库(linux下为.so)是在程序启动的时候加载到程序中。

1).动态链接库和共享库之间的区别是什么?

  我个人认为可以将它们看做是是相同的。如果真的希望了解它们构成上的区别,可以参考这一篇文章:http://www.cnblogs.com/likwo/archive/2012/05/09/2492225.html

2.为什么要用.so文件?

  1.由于共享库能被应用程序动态载入内存。所以,应用程序可以在需要时才将.so载入到内存中,这让程序的可维护性变得很高。比如QQ的视频功能需要升级,那么负责编写QQ的程序员不必将QQ所有代码都重写,只需将视频功能相关的.so文件重写即可。

  2.生成的.so文件可以认为是一个函数,其他程序就可以在它们的代码中直接调用这些函数来完成相同的工作(相对于其他直接给出源码的函数来讲,这应该是所谓的闭源)。这样的库(代码)可以重复调用,从而减小了代码的编写量,实现了代码的模块化。

3.如何在生成.so/.dll文件?

  1.关于生成.dll文件,可以参考我的这一篇简短的介绍:http://www.cnblogs.com/vincentX/p/4798830.html

  2.生成.so文件:

  举一个简单的例子,我们来实现两个数相加的功能:

  1.首先新建2个文件,分别命名为test.h test.c tmp.c

  2.将如下代码写入test.h文件中:

1 int add(int, int);

  3.将如下代码写入test.c文件中:

1 #include "test.h"
2
3 int add(int a, int b) {
4     return a + b;
5 }

  4.将test.c编译成.so文件,bash命令如下:

1 gcc test.c -shared -fPIC -o test.so

    shared是生成共享库,-fPIC是声明使用位置无关代码。关于为什么需要加入-fPIC,我会在后面解答。

    这时候便在当前目录下生成了一个.so文件。

  5.接下来将如下代码写入tmp.c文件中:

1 #include <stdio.h>
2 #include "test.h"
3
4 int main() {
5     printf("Hello world\n");
6     printf("%d\n", add(2, 3));
7     return 0;
8 }

  6.编译tmp.c:

1 gcc tmp.c -o tmp ./test.so

  至此我们可以./tmp来测试一下是否正常使用刚刚写好的.so文件了。执行一下tmp文件: 

1 ./tmp

  结果如下:

1 Hello world
2 5

  说明生成的共享库可以使用了。

  我们来做一个小实验:此时把刚刚生成的.so文件删除掉,会有什么样的情况发生呢?

1 rm test.so
2 ./tmp

  此时会返回这样一个错误信息:

1 ./tmp: error while loading shared libraries: ./test.so: cannot open shared object file: No such file or directory

  找不到tmp中包含的共享库test.so。同时可以解释为,可执行文件的确是在运行前调用的.so文件,(因为此时的hello world也没有被输出)。当我们重新将test.so编译出来以后再执行tmp,便仍然可以正常运行。

4.关于-fPIC?

  在linux下制作共享库的“标准做法”是将.so文件编译成位置无关代码,然后生成.so文件。因此我在思考:-fPIC是否是必需的?因为不添加-fPIC的时候也可以正常运行。

  关于-fPIC的详细解释可以参见:http://www.cnblogs.com/cswuyg/p/3830703.html

 

转载请声明出处,谢谢合作。

时间: 2024-08-04 10:18:21

关于linux下GCC生成共享库(动态链接库)的探究的相关文章

Linux 下 GCC 编译共享库控制导出函数的方法

通过一些实际项目的开发,发现这样一个现象,在 Windows 下可以通过指定 __declspec(dllexport) 定义来控制 DLL(动态链接库)中哪些函数可以导出,暴露给其他程序链接使用,哪些函数是 DLL 内部自己使用:而在 Linux 下不存在 dllexport 这样的指示字,默认情况下 GCC 编译 SO(共享库)时把代码中的所有函数都导出了,那么如何实现 Windows 下的那种效果,由我们自己来控制共享库导出函数呢? 其实在 Linux 下也有类似的控制机制.在 GCC 帮

linux 下gcc生成intel汇编

留作备忘: gcc -S -masm=intel xxxx.c 生成elf可执行文件: gcc -o xxx xxxx.s linux 下gcc生成intel汇编,码迷,mamicode.com

Linux下Gcc生成和使用静态库和动态库详解

参考文章:http://blog.chinaunix.net/uid-23592843-id-223539.html 一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同(主要是编译器.汇编器和连接器的不同),因此二者库的二进制是不兼容的. 本文仅限于介绍linux下的库. 1.2库的种类 linux下的库有两种:静态库和共享库(动态库). 二者的不同

【转】Linux下gcc生成和使用静态库和动态库详解

一.基本概念 1.1 什么是库 在Windows平台和Linux平台下都大量存在着库. 本质上来说,库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同(主要是编译器.汇编器和连接器的不同),因此二者的库的二进制是不兼容的. 本文仅限于介绍linux下的库. 1.2 库的种类 linux下的库有两种:静态库和共享库(动态库). 二者的不同点在于代码被载入的时刻不同. 静态库的代码在编译过程中已经被载入可执行程序,因此体积较大. 共享库的代码是在可

Linux下gcc编译生成动态链接库*.so文件并调用它 是转载的

动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一点帮助.1.动态库的编译 下面通过一个例子来介绍如何生成一个动态库.这里有一个头文件:so_test.h,三个.c文件:test_a.c.test_b.c.test_c.c,我们将这几个文件编译成一个动态库:libtest.so. //so_test.h:#include "stdio.h"

linux下的静态连接库和动态链接库

对linux的静态连接库和动态链接库分不清楚,在看了一篇博文后,现在想做个自己的总结,以加深印象: 1.库的基本概念: 库是可执行代码的二进制形式,其可以被调入操作系统调入内存进行执行. 在window和linux系统,都存在各自的库,但是两种系统的库并不能兼容,因为它们的编译器,连接器,汇编器都是不相同的. 在windows下,静态连接库的后缀是.lib;动态链接库的后缀是.dll 在linux系统下,静态链接库的后缀是.a;动态链接库的后缀是.so 2.静态连接库和动态链接库的命名: 静态连

Linux下gcc编译控制动态库导出函数小结

Linux下gcc编译控制动态库导出函数小结 来源 https://www.cnblogs.com/lidabo/p/5703890.html 根据说明文档“How To Write Shared Libraries"介绍, 有四种方法: 1. 在方法声明定义时,加修饰:__attribute__((visibility("hidden"))) 就是说将不公开的函数都加上这个属性,没加的就是可见的 2. gcc 在链接时设置 -fvisibility=hidden,则不加 v

Linux下的动态连接库及其实现机制

Linux与Windows的动态连接库概念相似,但是实现机制不同.它引入了GOT表和PLT表的概念,综合使用了多种重定位项,实现了"浮动代码",达到了更好的共享性能.本文对这些技术逐一进行了详细讨论. 本文着重讨论x86体系结构,这是因为 (1)运行Linux的各种体系结构中,以x86最为普及: (2)该体系结构上的Windows操作系统广为人知,由此可以较容易的理解Linux的类似概念: 下表列出了Windows与Linux的近义词,文中将不加以区分: Windows Linux 动

Qt 共享库(动态链接库)和静态链接库的创建及调用

前言: 编译器 Qt Creator, 系统环境 win7 64 位 1.创建共享库: 新建文件或项目->选择 Library 和 c++ 库->选择共享库->下一步(工程名为 sharedlib) 生成的目录结构如图: 修改 sharedlib.h 中的代码: // sharedlib.h #ifndef SHAREDLIB_H #define SHAREDLIB_H #include "sharedlib_global.h" class SHAREDLIBSHAR