分享

-fPIC

 WUCANADA 2012-01-18
(2009-01-14 10:34:47)

共享库是目标文件的集合,但是这些目标文件是由编译程序按照特殊方式生成的。对象模块的每个地址(变量引用和函数调用)都是相对地址,不是绝对地址。因此允许在运行程序的时候,可以动态加载和执行共享模块。

  构造共享库最基本的一步是编译库中的对象模块。例如,下面的两个源文件名为first.csecond.c


#include <stdio.h>

void first()
{
 printf("The first hello from a shared library\n");
}


#include <stdio.h>

int second()
{
 printf("The second hello from a shared library\n");
}

  使用下列命令可将这两个源文件编译成一个目标文件:

 $ gcc -c -fpic first.c second.c

  选项-c明确指出编译程序要生成.o目标文件。而选项-fpic是的输出的对象模块式按照可重定位地址(relocatable addressing)方式生成的。缩写pic代表位置独立代码(position independent code)。

  下面的gcc命令使用目标文件构造共享库hello.so

$ gcc -shared first.o second.o -o hello.so

  选项-o为输出文件命令,而后缀.so告诉GCC该目标文件是要连接到共享库的。通常,连接程序要为主函数main()定位,并用它作为程序的入口,但输出模块没有这样的入口,选项-shared对防止出错信息是必要的。

  编译程序将后缀为.c的文件看作是C语言源代码程序,并且知道如何将它编译成目标文件。因此,可以将前面的两个命令合成一个命令,用下面的命令可以将模块直接编译并保存为共享库:

$ gcc -fpic -shared first.c second.c -o hello.so

  下面试文件main.c中的程序,是主函数,它调用了共享库中的两个函数:


void first(void);
void second(void);

int main(int argc, char **argv)
{
 first();
 second();

 return 0;
}

  可以使用下列命令将该程序编译并链接到共享库:

$ gcc main.c hello.so -o hello

  程序hello已经可以运行了,但要运行程序必须也要能够定位共享库hello.so,因为库中的函数必须在运行的时候载入。

  需要注意的是,当前工作目录可能不在共享库的查找路径中,因此需要使用如下的命令行设定环境变量LD_LIBRARY_PATH

$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./

  运行结果:

$ ./hello
The first hello from a shared library
The second hello from a shared library

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多