C语言 超详细讲解链接器

yizhihongxing

C语言 超详细讲解链接器

什么是链接器

在C语言编写代码时,我们往往需要调用一些库函数,比如printfmalloc等等。这些库函数在我们的代码文件中并没有实现,而是存储在系统或其他库文件中,我们需要通过链接器把这些函数与我们编写的代码组合在一起,生成可执行程序。

链接器主要负责以下两个任务:
- 符号解析:将目标文件中引用的符号与定义的符号建立联系。
- 符号重定位:将目标文件中引用的符号地址引用替换为实际的地址。

静态链接

静态链接是将所有目标文件和库文件的编译结果一起链接成一个独立的可执行文件。这样生成的可执行文件包含了所有代码和数据,以及被程序引用的库函数和操作系统函数。

静态链接的过程:
1. 预处理目标文件:将源代码预处理成为独立的*.o目标文件。

gcc -c a.c -o a.o
  1. 预处理库文件:将需要的库文件进行预处理,生成库目标文件。
gcc -c lib.c -o lib.o
  1. 静态链接:
gcc a.o lib.o -o prog
  1. 运行可执行文件:
./prog

示例1:工程调用printf函数

main.c文件如下:

#include <stdio.h>

int main()
{
    printf("Hello, world!\n");
    return 0;
}

编译过程:

gcc -o main main.c

执行结果:

Hello, world!

示例2:工程调用某个库函数

math.h头文件中包含了数学库函数sqrt的声明,我们可以通过链接数学库来使用这个函数。

main.c文件如下:

#include <stdio.h>
#include <math.h>

int main()
{
    double result = sqrt(2.0);
    printf("sqrt(2.0)=%f\n", result);
    return 0;
}

编译过程:

gcc -o main main.c -lm

-lm参数表示链接数学库。

执行结果:

sqrt(2.0)=1.414214

动态链接

动态链接是指在程序运行时才将程序需要的库文件动态链接到程序中。这样生成的可执行文件不包含库函数和操作系统函数的代码,而是在程序执行时才从动态库文件中加载。

动态链接的优点是可以减少可执行程序的大小,减少内存占用,但是需要一定的额外开销来加载动态链接库。

动态链接过程:
1. 预处理目标文件:同静态链接。

gcc -c a.c -o a.o
  1. 创建共享库:将编译生成的*.o目标文件生成共享连接库。其中,Linux 需要将后缀.so,链接库标记添加--shared,Windows 需要将后缀.dll,链接库标记添加/DLL
gcc -shared lib.c -o lib.so
  1. 动态链接可执行文件:
gcc -o prog a.o -L. -l:lib.so
  1. 运行可执行文件
./prog

示例3:工程调用共享库函数

shared_lib.c文件如下:

#include <stdio.h>

void show(int n)
{
    printf("show: %d\n", n);
}

编译成动态库:

gcc -shared shared_lib.c -o libshared_lib.so

Windows,编译成dll:

gcc -shared shared_lib.c -o shared_lib.dll

main.c文件如下:

#include <stdio.h>

void show(int);

int main()
{
    show(3);
    return 0;
}

编译动态链接版本可执行文件:

gcc -o dynamic main.c -L. -l:libshared_lib.so

Windows,编译dll:

gcc -o dynamic.exe main.c -L. -l:shared_lib.dll

执行结果:

show: 3

总结

链接器是任何编程语言工具链中都不可缺少的一环。静态链接和动态链接都是链接器的重要功能,对C语言程序的编译和运行有着至关重要的作用。对于理解代码模块化及整体编译过程更是有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言 超详细讲解链接器 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • 微信小程序使用uni-app开发小程序及部分功能实现详解

    微信小程序使用uni-app开发小程序及部分功能实现详解 一、uni-app简介 uni-app是DCloud提供的一款跨平台开发框架,可以通过一套代码在不同平台上运行(H5、小程序、APP)。该框架采用Vue.js作为前端开发框架,并提供了一系列的API和插件,让程序开发更加简单。 二、微信小程序使用uni-app开发 1. 安装uni-app 在命令行工…

    C 2023年5月23日
    00
  • C语言 存储类详解及示例代码

    “C语言 存储类详解及示例代码”是一篇介绍C语言中存储类的文章。本文讲解了C语言中的四种存储类(自动存储类、静态存储类、寄存器存储类、外部存储类)的特点、使用方法以及示例代码。 自动存储类 自动存储类是指在函数或代码块内定义的变量。它们通常在代码块内使用,并且在代码块外是不可见的。自动存储类变量的值在函数或代码块的开始处自动初始化为随机值。例如,在以下代码中…

    C 2023年5月24日
    00
  • YII Framework教程之异常处理详解

    YII Framework教程之异常处理详解 在YII Framework中,异常处理是非常重要的一个方面。合理处理异常可以有效提高程序的健壮性、可靠性和安全性。下面是关于YII Framework异常处理的详解。 异常处理的作用 异常处理可以有效帮助程序员更好地捕获和处理程序中可能出现的异常,比如错误的用户输入、系统异常或者外部错误。合理的异常处理可以让程…

    C 2023年5月23日
    00
  • shell 通过makefile传参给c语言的实现示例

    下面是详细讲解 shell 通过 makefile 传参给 C 语言的实现示例的完整攻略: 1. 确定传参的方式 命令行参数:在程序执行时,可以通过命令行传入参数,使用 main() 函数中的 argc 和 argv 进行接收; 环境变量:通过设置和获取环境变量,来传递参数; 读取配置文件:在程序运行前读取配置文件,将需要的参数传入程序中; Makefile…

    C 2023年5月23日
    00
  • C++中Boost的智能指针scoped_ptr

    C++中Boost的智能指针scoped_ptr 简介 C++中的RAII(资源获取即初始化)技术可以帮助程序员在程序运行过程中自动管理资源的分配和释放,以避免资源泄漏等问题。RAII技术的实现依赖于智能指针,在C++标准库中,已经提供了shared_ptr、unique_ptr和weak_ptr等智能指针类型,但是这些类型都不是线程安全的。 Boost库是…

    C 2023年5月23日
    00
  • java生成json数据示例

    生成JSON数据是Java编程过程中非常常见的需求,下面是Java生成JSON数据的完整攻略。 示例一:将Java对象转换为JSON数据 Java中的对象可以轻松转换为JSON数据,这可以通过Java提供的Jackson框架来实现。以下是一个简单的示例: ObjectMapper mapper = new ObjectMapper(); SomeObject…

    C 2023年5月23日
    00
  • C#使用LitJson解析JSON的示例代码

    首先我们需要了解什么是JSON和LitJson,JSON是一种轻量级的数据交换格式,而LitJson则是一款C#的JSON序列化和反序列化库。 接下来,我们将用LitJson来解析JSON数据。以下是示例代码: 引用LitJson 在项目中引入LitJson.dll并添加LitJson命名空间 using LitJson; 创建一个类来接收JSON数据 在此…

    C 2023年5月23日
    00
  • Lua教程(六):编译执行与错误

    Lua教程(六):编译执行与错误 Lua是一门解释型脚本语言,它的源代码需要经过编译才能在计算机上运行。本篇教程将介绍如何编译和执行Lua代码,以及如何处理代码中的错误。 编译执行Lua代码 Lua交互模式 在安装了Lua解释器后,打开终端或命令行,输入lua命令即可进入Lua交互模式。在交互模式下,可以逐行输入Lua代码并立即执行,也可以使用dofile或…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部