日期:2014-05-16  浏览次数:20652 次

在Linux上用GCC创建共享库(Shared libraries with GCC on Linux)

英文原文:http://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html

         库是程序员必须的工具,它是已经编译过的代码。库通常提供通用的功能,例如链表和二叉树等数据结构,或者特定的功能,例如MySQL等数据库服务器访问接口。

         多数大型软件项目有多个部件组成,这些部件有可能在其它项目中用到,或者你只是想分离多个部件以便组织。当你有一个可重用或者逻辑上独立的函数集合,建立一个库使你不用总是复制代码到现在的项目然后重新编译,而且可以保持不同的模块的分离,修改其中一个不会影响其他模块。只要一个库被写好且测试过,就可以安全地重用。

         建立静态库是相当简单的,这里只讲如何建立共享库(动态库)。

         在开始之前,先看看从源代码到可执行程序这个过程中发生什么:

         1、C语言预处理:这个阶段,任何以#开头,例如#define和#include的行都会被处理,也就是宏替换和文件包含。

         2、编译:将预处理后的源代码转换成汇编代码,然后在转换成机器代码。

         3、链接:将objectfiles和库链接生成可执行程序。对于静态库,链接器把库本身放到最终的可执行程序中;而对于共享库,只是把对库的引用放到里面。

         4、装入:当我们执行程序的时候,检查程序对共享库的引用,将动态库映射到程序中。

第3和第4步是共享库比较神奇却也让人困惑的地方。

foo.h:

#ifndef foo_h__
#define foo_h__
extern void foo(void);
#endif  // foo_h__

foo.c:

#include <stdio.h>
void foo(void)
{
    puts("Hello, I'm a shared library");
}

main.c:

#include <stdio.h>
#include "foo.h"
int main(void)
{
    puts("This is a shared library test...");
    foo();
    return 0;
}

foo.h定义了我们的库的接口,一个函数foo(),foo.c是函数实现的地方。

本例子在路径 /home/username/foo

Step 1:编译不依赖于位置的代码

将库的源代码编译成位置无关的代码

$ gcc -c -Wall -Werror -fpic foo.c

Step 2: 由目标文件(object file)生成共享库

将库的名称定为 libfoo.so:

gcc -shared -o libfoo.so foo.o

Step 3: 链接共享库

先编译 main.c然后链接 libfoo最终生成程序“test.”-lfoo选项是用来寻找