linux 动态库的两种使用方式

前段时间遇到这样这个面试题:没有头文件,能调用动态库里面的函数吗?

接下来我们可以一起来了解动态库有哪些使用方式——

动态库(Dynamic Link Library,简称DLL,在Windows环境下)或共享对象文件(Shared Object,简称SO,在Linux/Unix环境下)是包含可由多个程序同时使用的代码和数据的库文件。动态库的使用方式主要分为两大类:隐式调用(隐式链接)和显式调用(显式链接)。

一、隐式调用(隐式链接)

隐式调用是动态库的一种常见使用方式,它在程序编译时就确定了要使用的动态库。

1、制作动态库

  • 动态库对应的源文件test_lib.c:
//test_lib.c
#include <stdio.h>

void func_lib(void) 
{
       printf("hello!I am lib.\n");
       return ;
}
  • 动态库对应的头文件 test_lib.h:

void func_lib(void) ;

编译命令如下:

gcc test_lib.c -fPIC -shared -o libtest.so

说明: -fPIC   :表示生成位置无关代码(PIC:Position Independent Code)
      -shared : 表示创建生成动态共享库

2、在程序中声明和链接动态库

  • 在程序中包含动态库的头文件,以便声明需要使用的函数和数据。
  • 在编译程序时,通过编译器选项指定动态库的路径和名称。这通常涉及到在编译命令中添加-L(指定库文件搜索路径)和-l(指定库文件名称,省略前缀lib和后缀.so.dll)选项。
  • 在链接阶段,链接器会将程序中引用的动态库函数和数据链接到可执行文件中,但不会将动态库的代码和数据复制到可执行文件中,而是保留对动态库的引用。

测试文件 main.c 内容如下:

#include <stdio.h>
#include "test_lib.h"

int main(void) 
{
    func_lib();
    return 0;
}

编译命令如下(和链接静态库命令基本一样):

gcc main.c -L. -ltest -o main

说明:编译的时候指定了libtest.so(上述编译好的动态库)

3、程序运行时加载动态库

  • 当程序启动时,操作系统会根据可执行文件中的动态库引用信息,自动加载所需的动态库到内存中。
  • 程序运行时,可以像调用静态库中的函数一样调用动态库中的函数。

运行测试:

export LD_LIBRARY_PATH=$PWD/:$LD_LIBRARY_PATH

./main

二、显式调用(显式链接)

显式调用允许程序在运行时根据需要动态地加载和卸载动态库,这种方式提供了更大的灵活性。

1、加载动态库

在程序运行时,使用dlopen函数来加载动态库。

2、获取函数地址

使用 dlsym() 通过函数名获取动态库中函数的地址。

3、调用函数

通过上一步获取的函数地址(通常是函数指针)来调用动态库中的函数。

4、卸载动态库

在不再需要动态库时,使用 dlclose() 来卸载动态库,释放其占用的资源。

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

void (* pFuc)(void) = NULL;  //函数指针

int main(void) 
{
        void *handle = dlopen("./libtest.so", RTLD_NOW); //打开动态库
        if (handle == NULL) 
	{
                printf("%s\n", dlerror());
                return -1;
        }

        pFuc = dlsym(handle, "func_lib");  // 查找需要使用的符号
        if ((pFuc != NULL) && (NULL == dlerror()) ) 
	{
        	pFuc();  // 调用动态库中的函数
        }
	else 
	{
                printf("get test_print FUNC failed.\n");
        }

        dlclose(handle);  // 卸载动态库
        return 0;
}

编译运行:

gcc main.c -ldl -o main

./main

可以看到,使用这种方式,不需要引用头文件,也可以使用动态库里面的函数!

此外,试了以下方式,也可以不需要引用头文件:

qq群交流:698593923

觉得有帮助的话,打赏一下呗。。

           

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值