• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > linux使用gcc编译c语言共享库步骤

linux使用gcc编译c语言共享库步骤

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了gcc编译c语言,c语言编译器gcc下载,c语言gcc,c语言编译器gcc,linux gcc c 下载等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

对任何程序员来说库都是必不可少的。所谓的库是指已经编译好的供你使用的代码。它们常常提供一些通用功能,例如链表和二叉树可以用来保存任何数据,或者是一个特定的功能例如一个数据库服务器的接口,就像MySQL。

大部分大型的软件项目都会包含若干组件,其中一些你发现可以用在其他项目中,又或者你仅仅出于组织目的将不同组件分离出来。当你有一套可复用的并且逻辑清晰的函数时,将其构建为一个库会十分有用,这样你就不将这些源代码拷贝到你的源代码中,而且每次都要再次编译它们。除此之外,你还可以保证你的程序各模块隔离,这样你修改其中一个模块时也不会影响到其他的模块。一旦你写好一个模块并且通过测试,你就可以无限次地安全地复用它,这可以节省大量时间和麻烦。
构建静态库太简单了,对此我们几乎不会遇到什么问题。我不想说明如何构建静态库。在此我只讨论共享库,因为对大多数人来说它更加难懂。

在我们正式开始前,让我们列一下纲要来了解从源代码到运行程序之间发生了什么:

预处理:这个阶段处理所有预处理指令。基本上就是源代码中所有以#开始的行,例如#define和#include。
编译:一旦源文件预处理完毕,接下来就是编译。因为许多人提到编译时都是指整个程序构建过程,因此本步骤也称作“compilation proper”。本步骤将.c文件转换为.o文件。
连接:到这一步就该将你所有的对象文件和库串联起来使之成为最后的可运行程序。需要注意的是,静态库实际上已经植入到你的程序中,而共享库,只是在程序中包含了对它们的引用。现在你有了一个完整的程序,随时可以运行。当你从shell中启动它,它就被传递给了加载器。
加载:本步骤发生在你的程序启动时。首先程序需要被扫描以便引用共享库。程序中所有被发现的引用都立即生效,对应的库也被映射到程序。
 

第3步和第4步就是共享库的奥秘所在。

现在,开始我们一个简单的示例。

foo.h:

main.c:

oo.h 定义了一个接口连接我们的库,一个简单的函数,foo()。foo.c包含了这个函数的实现,main.c是一个用到我们库的驱动程序。

为了更好的演示本例子,所有代码都放在/home/username/foo目录下。

Step 1: 编译无约束位代码

我们需要把我们库的源文件编译成无约束位代码。无约束位代码是存储在主内存中的机器码,执行的时候与绝对地址无关。

Step 2: 从一个对象文件创建共享库

现在让我们将对象文件变成共享库。我们将其命名为libfoo.so:

Step 3: 连接共享库

如你所见,一切都很简单。我们现在有了一个共享库。现在我们编译我们的main.c并且将它连接到libfoo。我们将最终的运行程序命名为test。注意:-lfoo选项并不是搜寻foo.o,而是libfoo.so。GCC编译器会假定所有的库都是以lib开头,以.so或.a结尾(.so是指shared object共享对象或者shared libraries共享库,.a是指archive档案,或者静态连接库)。

告诉GCC去哪找共享库

Uh-oh!连接器不知道该去哪里找到libfoo。GCC有一个默认的搜索列表,但我们的目录并不在那个列表当中。我们需要告诉GCC去哪里找到libfoo.so。这就要用到-L选项。在本例中,我们将使用当前目录/home/username/foo:

Step 4: 运行时使用库

好的,没有异常。让我们运行一下程序:

Oh no! 加载器不能找到共享库。我们没有将它安装到标准位置,因此我们需要帮一帮加载器。我们有两个选项:使用环境变量LD_LIBRARY_PATH或者rpath。让我们先看看LD_LIBRARY_PATH:

使用LD_LIBRARY_PATH

目前什么都没有。现在把我们的工作目录添加到LD_LIBRARY_PATH中:

为什么还报错?虽然我们的目录在LD_LIBRARY_PATH,但是我们还没有导出它。在Linux中,如果你不将修改导出到一个环境变量,这些修改是不会被子进程继承的。加载器和我们的测试程序没有继承我们所做的修改,不过放心,要修复这个问题很简单:

很好,运行正常!LD_LIBRARY_PATH很适合做快速测试,尤其是那些你没有管理员权限的系统。另一方面,导出LD_LIBRARY_PATH变量意味着可能会造成其他依赖LD_LIBRARY_PATH的程序出现问题,因此在做完测试后最好将LD_LIBRARY_PATH恢复成之前的样子。

使用rpath

现在让我们来试试rpath,首先需要清除LD_LIBRARY_PATH,确保我们是使用rpath来搜索库文件。Rpath,或者称为run path,是种可以将共享库位置嵌入程序中的方法,从而不用依赖于默认位置和环境变量。我们在连接环节使用rpath。注意“-Wl,-rpath=/home/username/foo”选项。-Wl会发送以逗号分隔的选项到连接器,因此我们通过它发送-rpath选项到连接器。(译者按:逗号分隔符后面没有空格,而是紧跟需要发送的选项。本例中为-rpath。一定注意"-Wl,-rpath"之间没有空格。)
$ gcc -L/home/user

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • linux使用gcc编译c语言共享库步骤

相关文章

  • 2017-05-28C++调用迅雷接口解析XML下载功能(迅雷下载功能)
  • 2017-05-28VC++实现通过API来查看程序错误信息的方法
  • 2017-05-28掌握C++编程中反斜杠续行符的使用方法
  • 2017-05-28C语言中宏定义使用的小细节
  • 2017-05-28Cocos2d-x中获取系统时间和随机数实例
  • 2017-05-28C++ 类的静态成员深入解析
  • 2017-05-28详解安卓系统中的Android.mk文件
  • 2017-05-28c++遍历lua table示例
  • 2017-05-28解析C++编程中异常相关的堆栈展开和throw()异常规范
  • 2017-05-28C 语言基础教程(我的C之旅开始了)[七]

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 如何寻找数组中的第二大数
    • 浅析C和C++函数的相互引用
    • C++实现从输入中读取字符串
    • 解决了个困扰了2天的问题,定点运算问题
    • C++11右值引用和std::move语句实例解析(推荐)
    • C++设计模式之抽象工厂模式
    • C++模板特例化应用实例
    • 讲解C++中的枚举类型以及声明新类型的方法
    • C++调用Python基础功能实例详解
    • C/C++ 读取16进制文件的方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有