非典型性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

相关文章

在Linux系统上连接GitHub的方法步骤(适用2025年)

《在Linux系统上连接GitHub的方法步骤(适用2025年)》在2025年,使用Linux系统连接GitHub的推荐方式是通过SSH(SecureShell)协议进行身份验证,这种方式不仅安全,还... 目录步骤一:检查并安装 Git步骤二:生成 SSH 密钥步骤三:将 SSH 公钥添加到 github

Go语言使用select监听多个channel的示例详解

《Go语言使用select监听多个channel的示例详解》本文将聚焦Go并发中的一个强力工具,select,这篇文章将通过实际案例学习如何优雅地监听多个Channel,实现多任务处理、超时控制和非阻... 目录一、前言:为什么要使用select二、实战目标三、案例代码:监听两个任务结果和超时四、运行示例五

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl

Python pandas库自学超详细教程

《Pythonpandas库自学超详细教程》文章介绍了Pandas库的基本功能、安装方法及核心操作,涵盖数据导入(CSV/Excel等)、数据结构(Series、DataFrame)、数据清洗、转换... 目录一、什么是Pandas库(1)、Pandas 应用(2)、Pandas 功能(3)、数据结构二、安

C语言中%zu的用法解读

《C语言中%zu的用法解读》size_t是无符号整数类型,用于表示对象大小或内存操作结果,%zu是C99标准中专为size_t设计的printf占位符,避免因类型不匹配导致错误,使用%u或%d可能引发... 目录size_t 类型与 %zu 占位符%zu 的用途替代占位符的风险兼容性说明其他相关占位符验证示

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

2025版mysql8.0.41 winx64 手动安装详细教程

《2025版mysql8.0.41winx64手动安装详细教程》本文指导Windows系统下MySQL安装配置,包含解压、设置环境变量、my.ini配置、初始化密码获取、服务安装与手动启动等步骤,... 目录一、下载安装包二、配置环境变量三、安装配置四、启动 mysql 服务,修改密码一、下载安装包安装地

C语言进阶(预处理命令详解)

《C语言进阶(预处理命令详解)》文章讲解了宏定义规范、头文件包含方式及条件编译应用,强调带参宏需加括号避免计算错误,头文件应声明函数原型以便主函数调用,条件编译通过宏定义控制代码编译,适用于测试与模块... 目录1.宏定义1.1不带参宏1.2带参宏2.头文件的包含2.1头文件中的内容2.2工程结构3.条件编

电脑提示d3dx11_43.dll缺失怎么办? DLL文件丢失的多种修复教程

《电脑提示d3dx11_43.dll缺失怎么办?DLL文件丢失的多种修复教程》在使用电脑玩游戏或运行某些图形处理软件时,有时会遇到系统提示“d3dx11_43.dll缺失”的错误,下面我们就来分享超... 在计算机使用过程中,我们可能会遇到一些错误提示,其中之一就是缺失某个dll文件。其中,d3dx11_4

Linux下在线安装启动VNC教程

《Linux下在线安装启动VNC教程》本文指导在CentOS7上在线安装VNC,包含安装、配置密码、启动/停止、清理重启步骤及注意事项,强调需安装VNC桌面以避免黑屏,并解决端口冲突和目录权限问题... 目录描述安装VNC安装 VNC 桌面可能遇到的问题总结描js述linux中的VNC就类似于Window