C语言 --- 动态库的两种使用方式说明

概述
动态库的使用分为两种方式(按照编码内容,编译方式及动态库加载时机来区分):

  • 显示调用
  • 隐式调用
      

1、动态库的制作

动态库测试内容如下:

  • 动态库对应的源文件 “test_lib.c”
#include "stdio.h"

void test_print(void) {
       printf("======= This is a test line.\n");
       return;
}
  • 动态库对应的头文件 “test_lib.h”
void test_print(void);

编译命令如下:

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

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

  
  
2、隐式调用(程序启动运行前加载动态库)
  在代码中没有指明需要的动态库,只包含库的头文件和库函数,需要在编译时来指明需要的动态库,软件启动运行前会加载动态库。

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

#include 
#include "test_lib.h"

int main(void) {
        printf("========= start...\n");
        test_print();
        return 0;
}

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

gcc test_bin1.c -L. -ltest -o test1

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

测试1:没有指定动态库路径,且没有将生成的动态库拷贝到系统路径下,测试结果如下图:
在这里插入图片描述
Error:报错找不到动态库 libtest.so

没有打印main函数入口的内容,说明动态库加载是在软件启动时进行的。

测试2:指定动态库的路径后(也可以将动态库复制到系统目录下),测试结果如下图:C语言 --- 动态库的两种使用方式说明_第1张图片

  
  
3、显示调用 (程序运行过程中加载动态库)
  在代码中明确指出需要的动态库,不用在编译时指定。软件运行过程中,使用特定的函数来加载动态库,使用特定函数通过符号名来查找动态库内的函数或变量,并调用。

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

#include 
#include 
#include "test_lib.h"

int main(void) {
        void * handle = NULL;
        void (* pFuc)(void) = NULL;  //函数指针
        printf("========= start...\n");

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

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

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

编译命令如下:

gcc test_bin2.c -ldl -o test2

说明:不需要指定libtest.so,但是需要链接libdl.so(或者libdl.a)库,因为使用了libdl库中的函数

测试1:没有指定动态库路径,测试结果如下图:
在这里插入图片描述
Error::报错找不到动态库 libtest.so

有打印main函数入口的内容,说明软件是可以启动的,动态库是在软件运行过程中加载的。

测试2:指定动态库的路径后,测试结果如下图:
C语言 --- 动态库的两种使用方式说明_第2张图片
  
  
4、附录
对应测试例子的Makefile文件如下:

all: test1 test2

test1:test_bin1.c libtest.so
        gcc test_bin1.c -L. -ltest -o test1

test2:test_bin2.c
        gcc test_bin2.c -ldl -o test2

libtest.so:test_lib.c
        gcc $^ -fPIC -shared -o $@

clean:
        rm -f libtest.so test1 test2


.PHONY: clean all

C语言 --- 动态库的两种使用方式说明_第3张图片

你可能感兴趣的:(c语言,开发语言)