非典型性C语言教程- 0.4 连接

2024-02-08 05:18

本文主要是介绍非典型性C语言教程- 0.4 连接,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

0.2 里面说过,当你使用gcc -o hello hello.c 时,gcc实际是先调用cpp预处理hello.c中的预处理命令,再自己编译之,最后调用ld进行连接生成可执行文件。Windows下是cl.exe 和link.exe。

用- c选项可以让编译器不连接,如 gcc -c hello.c,或是cl -c hello.c 这样会只将源文件编译成目标文件。Unix下叫hello.o,Windows下叫hello.obj。目标文件是不能执行的,但是目标文件中已经是可以 执行的机器指令了。其实目标文件和最后生成的可执行文件一样,都是一组函数(函数就是一段一段的机器指令),两者的区别在于目标文件中对函数的调用都是按 名字调用的,而可执行程序中已经是按地址调用了。先举例子,比如hello.c 程序中调用了printf("hello.c");。编译成的目标文件中,会有一个符号表,其中有一个符号叫printf,并且表明他是一个函数。但是由 于这个函数实际在标准库中,所以还不知道这个函数的具体细节,只有符号在那里。Hello world例子中,自己写的只有一个源文件,编译之后只需要与C语言的标准库连接就可以。

C语言的标准库实际就是一组函数。在 Windows下你安装了VC或是VS会给你安装上,在%VCHOME%/lib目录下,叫msvcrt.lib。这个lib文件实际使用的是% Windows%/system32下的msvcrt.dll。在Unix下在/usr/lib下,一般叫libc.so或是glibc.so等名字。C 语言的标准库基本上是操作系统不可缺少的部分。

首先生成hello.o或是hello.lib文件, 然后编译器调用ld或是link.exe将目标文件与C语言的标准库连接。连接在一起的时候,就可以决定, 每个函数的地址。比如main函数在0x400008出,prinft在0x400030 出。然后开始resovle符号。发现hello.o中有一个函数叫main,main中有一个对printf函数的调用,而C语言的标准库中的符号表中 有一个printf的函数,于是main中对printf的函数调用就转到标准库中printf函数的入口去了,函数调用就被翻译成一条汇编指令比如叫 call 0x400030了。最后会给程序加上一段stratup代码,这段代码完成一些初始化工作比如读参数,共享文件表等等,然后调用查找叫main的函数, 调用main。连接的过程就完成了。

当程序大的时候,需要多个源文件。会产生多个目标文件,可能目标文件a调用了目标文件b内的函数,这 些最后都是在连接的时候resolve的。还是先举例子,比如有两个文件hello.c和foo.c,那么编译的时候可以写成gcc -o hello hello.c foo.c,但是实际上编译器是这样作的,

gcc -c hello.c
gcc -c foo.c
ld -0 hello hello.o foo.o
上面3行命令的意义应该很清楚。

下面说说连接时容易产生的问题:
  1. unresolved symbol:这个问题一般是忘了连接某个库,或是连接某个目标文件造成的。
  2. 符号已定义,或是符号冲突:这个问题一般是有函数或变量重名造成的。
连接时候产生的错误并不报告是那个文件那一行错了,找起来会很麻烦。一般要用文件搜索找到相应的符号在那里。 

这篇关于非典型性C语言教程- 0.4 连接的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/690002

相关文章

C语言中联合体union的使用

本文编辑整理自: http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=179471 一、前言 “联合体”(union)与“结构体”(struct)有一些相似之处。但两者有本质上的不同。在结构体中,各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和。而在“联合”中,各成员共享一段内存空间, 一个联合变量

【Altium】查找PCB上未连接的网络

【更多软件使用问题请点击亿道电子官方网站】 1、文档目标: PCB设计后期检查中找出没有连接的网络 应用场景:PCB设计后期,需要检查是否所有网络都已连接布线。虽然未连接的网络会有飞线显示,但是由于布线后期整板布线密度较高,虚连,断连的网络用肉眼难以轻易发现。用DRC检查也可以找出未连接的网络,如果PCB中DRC问题较多,查找起来就不是很方便。使用PCB Filter面板来达成目的相比DRC

Java面试题:通过实例说明内连接、左外连接和右外连接的区别

在 SQL 中,连接(JOIN)用于在多个表之间组合行。最常用的连接类型是内连接(INNER JOIN)、左外连接(LEFT OUTER JOIN)和右外连接(RIGHT OUTER JOIN)。它们的主要区别在于它们如何处理表之间的匹配和不匹配行。下面是每种连接的详细说明和示例。 表示例 假设有两个表:Customers 和 Orders。 Customers CustomerIDCus

大语言模型(LLMs)能够进行推理和规划吗?

大语言模型(LLMs),基本上是经过强化训练的 n-gram 模型,它们在网络规模的语言语料库(实际上,可以说是我们文明的知识库)上进行了训练,展现出了一种超乎预期的语言行为,引发了我们的广泛关注。从训练和操作的角度来看,LLMs 可以被认为是一种巨大的、非真实的记忆库,相当于为我们所有人提供了一个外部的系统 1(见图 1)。然而,它们表面上的多功能性让许多研究者好奇,这些模型是否也能在通常需要系

人工和AI大语言模型成本对比 ai语音模型

这里既有AI,又有生活大道理,无数渺小的思考填满了一生。 上一专题搭建了一套GMM-HMM系统,来识别连续0123456789的英文语音。 但若不是仅针对数字,而是所有普通词汇,可能达到十几万个词,解码过程将非常复杂,识别结果组合太多,识别结果不会理想。因此只有声学模型是完全不够的,需要引入语言模型来约束识别结果。让“今天天气很好”的概率高于“今天天汽很好”的概率,得到声学模型概率高,又符合表达

Steam邮件推送内容有哪些?配置教程详解!

Steam邮件推送功能是否安全?如何个性化邮件推送内容? Steam作为全球最大的数字游戏分发平台之一,不仅提供了海量的游戏资源,还通过邮件推送为用户提供最新的游戏信息、促销活动和个性化推荐。AokSend将详细介绍Steam邮件推送的主要内容。 Steam邮件推送:促销优惠 每当平台举办大型促销活动,如夏季促销、冬季促销、黑色星期五等,用户都会收到邮件通知。这些邮件详细列出了打折游戏、

C语言 将“China”译成密码

将“China”译成密码,密码规律是:用原来的字母后面的第4个字母代替原来的字母。例如,字母“A”后面的第4个字母是“E”,用“E”代替“A”。因此,“China”应译为“Glmre”。编译程序用付赋初值的方法使c1,c2,c3,c4,c5这五个变量的值分别为“C”,“h”,“i”,“n”,“a”,经过运算,使c1,c2,c3,c4,c5分别变成“G”,“l”,“m”,“r”,“e”。分别用put

X-AnyLabeling使用教程

1.AI 模型自动分割标注使用教程 2.AI 模型自动目标检测标注使用教程

C语言入门系列:探秘二级指针与多级指针的奇妙世界

文章目录 一,指针的回忆杀1,指针的概念2,指针的声明和赋值3,指针的使用3.1 直接给指针变量赋值3.2 通过*运算符读写指针指向的内存3.2.1 读3.2.2 写 二,二级指针详解1,定义2,示例说明3,二级指针与一级指针、普通变量的关系3.1,与一级指针的关系3.2,与普通变量的关系,示例说明 4,二级指针的常见用途5,二级指针扩展到多级指针 小结 C语言的学习之旅中,二级

青龙面板2.9之Cdle傻妞机器人编译教程

看到有的朋友对傻妞机器人感兴趣,这里写一下傻妞机器人的编译教程。 第一步,这里以linux amd64为例,去官网下载安装go语言安装包: 第二步,输入下方指令 cd /usr/local && wget https://golang.google.cn/dl/go1.16.7.linux-amd64.tar.gz -O go1.16.7.linux-amd64.tar.gz