嵌入式开发学习(第二阶段 C语言笔记)

发布于:2025-06-06 ⋅ 阅读:(22) ⋅ 点赞:(0)

库文件

什么是库文件

库文件本质上是经过编译后生成的可被计算机执行的二进制代码。但注意库文件不能独立运行,库文件需要加载到内存中才能执行。库文件大量存在于Windows,Linux,MacOS等软件平台上。

库文件的分类

  • 静态库
    • Windows:xxx.lib
    • Linux:libxxx.a
  • 动态库(共享库)
    • Windows:xxx.dlll
    • Linux:libxxxx.so.major.minor(libmy.so.1.1)

注意:不同的软件平台因编译、链接器的不同,所生成的库文件是不兼容的。

静态库与动态库的区别
  1. 静态库链接时,将库中所有内容包含到最终的可执行程序中。

动态库链接时,将库中的符号信息包含到最终可执行文件中,在程序运行时,才将动态库中符号的具体实现加载到内存中。

静态库与动态库的优缺点
  1. 静态库
    • 优点:生成的可执行程序不再依赖静态文件
    • 缺点:可执行程序体积较大
  2. 动态库
    • 优点:生成的可执行程序体积小;动态库可被多个应用程序共享
    • 缺点:可执行程序运行依然依赖动态库文件
静态库与动态库对比

在这里插入图片描述

库文件创建

Linux系统下库文件命名规范:libxxxx.a(静态库) libxxxx.so(动态库)

静态库文件的生成
  1. 将需要生成库文件对应的源文件( *.c )通过编译(不链接)生成 *.o 目标文件
  2. ar 命令将生成的*.o打包生成libxxxx.a

库的生成:
在这里插入图片描述
库的使用 :

在这里插入图片描述

动态库文件的生成
  1. 利用源文件(*.c)通过编译(不链接)生成位置无关*.o目标文件
  2. 将目标文件链接为*.so文件

库的生成:

在这里插入图片描述

库的使用:
在这里插入图片描述

在这里插入图片描述

注意:如果在代码编译过程或者运行中链接了库文件,系统会到 /lib /usr/lib 目录下查找库文件,所以建议直接将库文件放在 /lib 或者/usr/lib,否则系统可能无法找到库文件,造成编译或者运行错误 。

扩展内容
  1. 查看应用程序(例如:app)依赖的动态库

    在这里插入图片描述

  2. 动态库使用方式:

    • 编译时链接动态库,运行时系统自动加载动态库

    • 程序运行时,手动加载动态库

    • 实现:

      • 涉及内容

        • 头文件:#include <dlfcn.h>
        • 接口函数:dlopen、dlclose、dlsym
        • 依赖库:-ldl
        • 句柄handler:资源的标识
      • 示例代码

        #include <stdio.h>
        #include <dlfcn.h>
        
        int main(int argc,char *argv[])
        {
        	// 1. 加载动态库 "/lib/libdlfun.so"
        	// - RTLD_LAZY: 延迟绑定(使用时才解析符号,提高加载速度)
        	// - 返回 handler 是动态库的句柄,失败时返回 NULL
        	void* handler = dlopen("/lib/libdlfun.so", RTLD_LAZY);
        	if (handler == NULL)
        	{
        		// 打印错误信息(dlerror() 返回最后一次 dl 相关错误的字符串)
        		fprintf(stderr, "dlopen 失败: %s\n", dlerror());
        	return -1;
        	} 
            // 2. 从动态库中查找符号 "sum"(函数名)
        	// - dlsym 返回 void*,需强制转换为函数指针类型 int sum(int*arr, int size);
            // - 这里假设 "sum" 是一个接受两个int*,int参数、返回 int 的函数
        	int (*paddr)(int*, int) = (int (*)(int*, int))dlsym(handler,"sum");
        	if (paddr == NULL)
        	{
        		fprintf(stderr, "dlsym 失败: %s\n", dlerror());
        		dlclose(handler); // 关闭动态库(释放资源)
        		return -1;
        	} 
            
            // 3. 调用动态库中的函数 "sum",计算{11,12,13,14,15}的累加和
        	int arr[5] = {11,12,13,14,15};
        	printf("sum=%d\n", paddr(arr, sizeof(arr)/sizeof(arr[0])));
            
        	// 4. 关闭动态库(释放内存和资源)
        	dlclose(handler);
        	return 0;
        }
        
      • 编译命令

        gcc demo06.c -ldl
        

网站公告

今日签到

点亮在社区的每一天
去签到