
<p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2022%2F0712%2F7a1a8a7cj00rewque003dd200u000gwg00zk00k0.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p id="11338E66"><strong>导读:</strong>学习如何用静态链接库将多个 C 目标文件结合到一个单个的可执行文件之中。</p><p id="11338E67">本文字数:4023,阅读时长大约: 5分钟</p><p><blockquote id="11338ECP">学习如何用静态链接库将多个 C 目标文件结合到一个单个的可执行文件之中。</blockquote></p><p id="11338E6B">使用 C 编写的应用程序时,通常有多个源码文件,但最终你需要编译成单个的可执行文件。</p><p id="11338E6C">你可以通过两种方式来完成这项工作:通过创建一个 静态(static) 库 或 一个 动态(dynamic) 库(也被称为 共享(shared) 库)。从创建和链接的方式来看,它们是两种不同类型的库。选择使用哪种方式取决于你的的具体场景。</p><p id="11338E6D">在 linux.cn 中,我演示了如何创建一个动态链接的可执行文件,这是一种更通用的方法。在这篇文章中,我将说明如何创建一个静态链接的可执行文件。</p><p id="11338E6E">使用静态库链接器</p><p id="11338E6F">链接器(linker)是一个命令,它将一个程序的多个部分结合在一起,并为它们重新组织内存分配。</p><p id="11338E6G">链接器的功能包括:</p><p id="11338E6H">◈ 整合一个程序的所有的部分</p><p id="11338E6I">◈ 计算出一个新的内存组织结构,以便所有的部分组合在一起</p><p id="11338E6J">◈ 恢复内存地址,以便程序可以在新的内存组织结构下运行</p><p id="11338E6K">◈ 解析符号引用</p><p id="11338E6L">链接器通过这些功能,创建了一个名称为可执行文件的一个可运行程序。</p><p id="11338E6M">静态库是通过复制一个程序中的所有依赖库模块到最终的可执行镜像来创建的。链接器将链接静态库作为编译过程的最后一步。可执行文件是通过解析外部引用、将库例程与程序代码结合在一起来创建的。</p><p id="11338E6N">创建目标文件</p><p id="11338E6O">这里是一个静态库的示例以及其链接过程。首先,创建带有这些函数识别标志的头文件:</p><p><ol><li id="11338EAK"></p><p id="11338E6P"></p><p></li><li id="11338EAL"></p><p id="11338E6Q"></p><p></li><li id="11338EAM"></p><p id="11338E6R"></p><p></li><li id="11338EAN"></p><p id="11338E6S"></p><p></li></ol></p><p id="11338E6T">使用这些函数定义来创建、、和文件。我将把所有的代码都放置到一个代码块中,请将其分为四个文件,如注释所示:</p><p><ol><li id="11338EAO"></p><p id="11338E6U"></p><p></li><li id="11338EAP"></p><p id="11338E6V"></p><p></li><li id="11338EAQ"></p><p id="11338E70"></p><p></li><li id="11338EAR"></p><p id="11338E71"></p><p></li><li id="11338EAS"></p><p></li><li id="11338EAT"></p><p id="11338E73"></p><p></li><li id="11338EAU"></p><p id="11338E74"></p><p></li><li id="11338EAV"></p><p id="11338E75"></p><p></li><li id="11338EB0"></p><p id="11338E76"></p><p></li><li id="11338EB1"></p><p></li><li id="11338EB2"></p><p id="11338E78"></p><p></li><li id="11338EB3"></p><p id="11338E79"></p><p></li><li id="11338EB4"></p><p id="11338E7A"></p><p></li><li id="11338EB5"></p><p id="11338E7B"></p><p></li><li id="11338EB6"></p><p></li><li id="11338EB7"></p><p id="11338E7D"></p><p></li><li id="11338EB8"></p><p id="11338E7E"></p><p></li><li id="11338EB9"></p><p id="11338E7F"></p><p></li><li id="11338EBA"></p><p id="11338E7G"></p><p></li></ol></p><p id="11338E7H">现在,使用 GCC 来生成目标文件、、和:</p><p id="11338E7I">(LCTT 校注:关于“目标文件(object file)”,有时候也被称作“对象文件”,对此,存在一些译法混乱情形,称之为“目标文件”的译法比较流行,本文采用此译法。)</p><p><ol><li id="11338EBB"></p><p id="11338E7J"></p><p></li></ol></p><p id="11338E7K">选项跳过链接步骤,而只创建目标文件。</p><p id="11338E7L">创建一个名称为的静态库,接下来,移除目标文件,因为它们不再被需要。(注意,使用一个命令比使用一个命令更安全。)</p><p><ol><li id="11338EBC"></p><p id="11338E7M"></p><p></li><li id="11338EBD"></p><p id="11338E7N"></p><p></li><li id="11338EBE"></p><p id="11338E7O"></p><p></li><li id="11338EBF"></p><p id="11338E7P"></p><p></li></ol></p><p id="11338E7Q">现在,你已经创建了一个名称为的简单数学示例库,你可以在 C 代码中使用它。当然,也有非常复杂的 C 库,这就是他们这些开发者来生成最终产品的工艺流程,你和我可以安装这些库并在 C 代码中使用。</p><p id="11338E7R">接下来,在一些自定义代码中使用你的数学库,然后链接它。</p><p id="11338E7S">创建一个静态链接的应用程序</p><p id="11338E7T">假设你已经为数学运算编写了一个命令。创建一个名称为的文件,并将这些代码复制粘贴至其中:</p><p><ol><li id="11338EBG"></p><p id="11338E7U"></p><p></li><li id="11338EBH"></p><p id="11338E7V"></p><p></li><li id="11338EBI"></p><p id="11338E80"></p><p></li><li id="11338EBJ"></p><p></li><li id="11338EBK"></p><p id="11338E82"></p><p></li><li id="11338EBL"></p><p id="11338E83"></p><p></li><li id="11338EBM"></p><p id="11338E84"></p><p></li><li id="11338EBN"></p><p id="11338E85"></p><p></li><li id="11338EBO"></p><p id="11338E86"></p><p></li><li id="11338EBP"></p><p></li><li id="11338EBQ"></p><p id="11338E88"></p><p></li><li id="11338EBR"></p><p id="11338E89"></p><p></li><li id="11338EBS"></p><p id="11338E8A"></p><p></li><li id="11338EBT"></p><p></li><li id="11338EBU"></p><p id="11338E8C"></p><p></li><li id="11338EBV"></p><p id="11338E8D"></p><p></li><li id="11338EC0"></p><p id="11338E8E"></p><p></li><li id="11338EC1"></p><p id="11338E8F"></p><p></li><li id="11338EC2"></p><p id="11338E8G"></p><p></li><li id="11338EC3"></p><p id="11338E8H"></p><p></li><li id="11338EC4"></p><p id="11338E8I"></p><p></li><li id="11338EC5"></p><p id="11338E8J"></p><p></li></ol></p><p id="11338E8K">注意:第一行是一个语句,通过名称来引用你自己的库。</p><p id="11338E8L">针对创建一个名称为的对象文件:</p><p><ol><li id="11338EC6"></p><p id="11338E8M"></p><p></li></ol></p><p id="11338E8N">选项告诉 GCC 搜索在其后列出的头文件。在这个实例中,你通过单个点()来指定当前目录。</p><p id="11338E8O">链接和来生成最终的可执行文件。这里有两种方法来向 GCC 告知这一点。</p><p id="11338E8P">你可以指向文件:</p><p><ol><li id="11338EC7"></p><p id="11338E8Q"></p><p></li></ol></p><p id="11338E8R">或者,你可以具体指定库的路径及名称:</p><p><ol><li id="11338EC8"></p><p id="11338E8S"></p><p></li></ol></p><p id="11338E8T">在后面的那个示例中,选项告诉链接器来链接对象文件和对象文件来生成最终的可执行文件。选项指示链接器在下面的参数中查找库(类似于你使用所做的工作)。</p><p id="11338E8U">分析结果</p><p id="11338E8V">使用命令来验证它是静态链接的:</p><p><ol><li id="11338EC9"></p><p id="11338E90"></p><p></li><li id="11338ECA"></p><p id="11338E91"></p><p></li><li id="11338ECB"></p><p id="11338E92"></p><p></li></ol></p><p id="11338E93">使用命令,你将会看到该可执行文件不是动态链接的:</p><p><ol><li id="11338ECC"></p><p id="11338E94"></p><p></li><li id="11338ECD"></p><p id="11338E95"></p><p></li></ol></p><p id="11338E96">你也可以查看可执行文件的大小:</p><p><ol><li id="11338ECE"></p><p id="11338E97"></p><p></li><li id="11338ECF"></p><p id="11338E98"></p><p></li></ol></p><p id="11338E99">在我 linux.cn 的示例中,动态链接的可执行文件只占有 24K 大小。</p><p id="11338E9A">运行该命令来看看它的工作内容:</p><p><ol><li id="11338ECG"></p><p id="11338E9B"></p><p></li><li id="11338ECH"></p><p id="11338E9C"></p><p></li><li id="11338ECI"></p><p id="11338E9D"></p><p></li><li id="11338ECJ"></p><p id="11338E9E"></p><p></li><li id="11338ECK"></p><p></li><li id="11338ECL"></p><p id="11338E9G"></p><p></li><li id="11338ECM"></p><p id="11338E9H"></p><p></li><li id="11338ECN"></p><p id="11338E9I"></p><p></li><li id="11338ECO"></p><p id="11338E9J"></p><p></li></ol></p><p id="11338E9K">看起来令人满意!</p><p id="11338E9L">何时使用静态链接</p><p id="11338E9M">动态链接可执行文件通常优于静态链接可执行文件,因为动态链接会保持应用程序的组件模块化。假如一个库接收到一次关键安全更新,那么它可以很容易地修补,因为它存在于应用程序的外部。</p><p id="11338E9N">当你使用静态链接时,库的代码会“隐藏”在你创建的可执行文件之中,意味着在库每次更新时(相信我,你会有更好的东西),仅有的一种修补方法是重新编译和发布一个新的可执行文件。</p><p id="11338E9O">不过,如果一个库的代码,要么存在于它正在使用的具有相同代码的可执行文件中,要么存在于不会接收到任何更新的专用嵌入式设备中,那么静态连接将是一种可接受的选项。</p><p id="11338E9P">via:</p><p id="11338E9Q">作者: 选题: 译者: 校对:</p><p id="11338E9R">本文由 原创编译, 荣誉推出</p><p id="11338EA1">LCTT 译者 :郑</p><p id="11338EA5">翻译: 105.0 篇</p><p id="11338EA6">贡献: 1315 天</p><p id="11338EA9">2018-12-03</p><p id="11338EAB">2022-07-09</p><p id="11338EAC">https://linux.cn/lctt/robsean</p><p id="11338EAF">欢迎遵照 CC-BY-SA 协议规定转载,</p><p id="11338EAG">如需转载,请在文章下留言 “ 转载:公众号名称”,</p><p id="11338EAH">我们将为您添加白名单,授权“ 转载文章时可以修改”。</p>
讯享网

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/140295.html