第20课 链接过程简介

1. 链接器的意义

(1)每个C语言源文件被编译后生成目标文件,这些目标文件最终要被链接在一起生成可执行文件。

(2)链接器的主要作用是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确的衔接。

2. 静态链接

(1)由链接器在链接时将库的内容直接加入到可执行程序中

(2)Linux下静态链的创建和使用

①编译静态库源码:gcc –c  lib.c –o lib.o

②生成静态库文件:ar –q lib.a lib.o //将lib.o与其他文件打包到lib.a中

③使用静态库编译:gcc main.c lib.a –o main.out

【编程实例】静态链接示例

//slib.c库文件

char* name()
{
    return "Static Lib";
}

int add(int a, int b)
{
    return a + b;
}

//20-1.c

#include <stdio.h>

extern char* name();
extern int add(int a, int b);

int main()
{
    printf("Name: %s\n", name());
    printf("Result: %d\n", add(2, 3));

    return 0;
}

3. 动态链接

(1)可执行程序在运行时才动态加载库进行链接

(2)库的内容不会进入可执行程序当中

(3)Linux下动态库的创建和使用

  ①编译动态库源码:gcc –shared  dlib.c –o dlib.so

  ②使用动态库编译:gcc main.c -ldl –o main.out

(4)动态库的使用(关键的API调用)

  ①打开动态库:dlopen

  ②查找动态库中的函数并返回调用地址:dlsym

  ③关闭动态库:dlclose

【编程实验】动态链接示例

//dlib.c库

char* name()
{
    return "Dynamic Lib";
}

int add(int a, int b)
{
    return a + b;
}

//20-2.c

#include <stdio.h>
#include <dlfcn.h>

int main()
{

    //打开(加载)动态库
    void* pdlib = dlopen("./dlib.so", RTLD_LAZY);

    char* (*pname)();
    int (*padd)(int, int);

    if( pdlib != NULL )
    {
    //查找函数地址
        pname = dlsym(pdlib, "name");
        padd = dlsym(pdlib, "add");

        if( (pname != NULL) && (padd != NULL) )
        {
            printf("Name: %s\n", pname());
            printf("Result: %d\n", padd(2, 3));
        }

    //关闭动态库
        dlclose(pdlib);
    }
    else
    {
        printf("Cannot open lib ...\n");
    }

    return 0;

}

4. 小结

(1)链接是指将目标文件最终链接为可执行程序

(2)根据链接方式的不同,链接过程可以分为:

  ①静态链接:目标文件直接链接进入可执行程序

  ②动态链接:在程序启动后才动态加载目标文件

时间: 2024-10-09 03:46:37

第20课 链接过程简介的相关文章

C语言-第15课 - 编译过程简介

第15课  - 编译过程简介 1. 编译器做了什么 (1)预编译: l 处理所有的注释,以空格代替. l 将所有的#define删除,并且展开所有的宏定义. l 处理条件编译指令#if,#ifdef,#elif,#else,#endif. l 处理#include,展开被包含的文件. l 保留编译器需要使用的#pragma指令. 预处理指令:gcc -E file.c -o hello.i (2)编译 l 对预处理的文件进行一系列的词法分析,语法分析和语义分析: 词法分析主要分析关键字,标示符,

第19课 编译过程简介

1. 初始编译器            广义的编译器                                                                                        你可能不知道的事… 2. 预编译:指令示例——gcc –E file.c –o file.i (1)处理所有的注释,以空格代替 (2)将所有的#define删除,并且展开所有的宏定义 (3)处理条件编译指令#if.#ifdef.#elif.#else.#endif (4)

c++编译过程简介

了解编译过程的益处 c++工程相关的问题 什么是库?静态库和动态库又有什么区别? 头文件起什么作用? 编译过程简介 名词: 编译:把源文件中的源代码翻译成机器语言,保存到目标文件中.如果编译通过,就会把CPP转换成OBJ文件. 编译单元: 每个cpp就是一个编译单元,每个编译单元相互之间是独立且相互不知的.一个编译单元(Translation Unit)是指一个.cpp文件以及这所include的所有.h文件,.h文件里面的代码将会被扩展到包含它的.cpp文件里,然后编译器编译该.cpp文件为一

GCC编译链接过程

编译链接过程 代码 #cat main.c #include <stdio.h> int add(int x, int y); int sub(int x, int y); int mul(int x, int y); int div(int x, int y); int main(void) { printf("add:%d\n", add(1,2)); printf("sub:%d\n", sub(10,100)); printf("mul

Spark IMF传奇行动第20课:top N总结

版权声明:本文为博主原创文章,未经博主允许不得转载.作者:HaiziS 今晚听了王家林老师的Spark IMF传奇行动第20课:top N,作业是:scala写topGroup,且对组名key排序 代码如下: def main(args: Array[String]){ val conf = new SparkConf() //创建SparkConf对象 val sc = new SparkContext(conf) //通过传入SparkConf实例来定制Spark运行具体参数和配置信息来创建

C++编译与链接(1)-编译与链接过程

大家知道计算机使用的一系列的1和0 那个一个C++语言程序又是如何从一个个.h和.cpp文件变成包含1和0的可执行文件呢? 可以认为有以下的几个阶段 源程序->预处理->编译和优化->生成目标文件->链接->可执行文件 1.预处理 C++的预处理是指在C++程序源代码被编译之前,由预处理器对C++程序源代码进行的处理.这个过程并不对程序的源代码进行解析. 这里的预处理器(preprocessor)是指真正的编译开始之前由编译器调用的一个独立程序. 预处理器主要负责以下的几处

程序的编译链接过程

还是从HelloWorld开始说吧... #include <stdio.h> int main(int argc, char* argv[]) { printf("Hello World!\n"); return 0; } 从源文件Hello.cpp编译链接成Hello.exe,需要经历如下步骤: 可使用以下命令,直接从源文件生成可执行文件 linux: gcc -lstdc++ Hello.cpp -o Hello.out // 要带上lstdc参数,否则会报undef

第20课-数据库开发及ado.net 可空值类型,资料管理器,多条件查询,Case

第20课-数据库开发及ado.net 可空值类型,资料管理器,多条件查询,Case SqlHelper using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Data.SqlClient; using System.Text; namespace _02省市联动 { public static  class SqlHelper { //

windows下 php由5.2升级 5.4.20的蛋疼过程。。

在IDC 工作大半年了,还没有毕业,刚刚答辩完毕,感觉有蛋疼了,每天面对客户奇葩问题,面对奇葩客户[PS:不是装逼的-.-,只是发现小白客户真可怕],现在每天处理一些琐碎的事情,感觉人生的经验槽正在慢慢积蓄能量了,不禁一种舒爽的感觉啊~,IDC的大家应该了解点,小问题不会的问百度,问我哥(谷歌),大问题备份数据重装一下下~反正有模板. 今天遇到一个问题就是客户模板程序要用到 php 5.4版本以上的,客户用的独立服务器,PHP升级速来麻烦的蛋疼[当然这是我以为的,新手小问题自己也不免兴师动众的样