C语言 --- 动态库的两种使用方式说明
概述 动态库的使用分为两种方式(按照编码内容,编译方式及动态库加载时机来区分):
- 
 显示调用 隐式调用   
1、动态库的制作
动态库测试内容如下:
- 
 动态库对应的源文件 “test_lib.c”
#include "stdio.h"
void test_print(void) {
          
   
       printf("======= This is a test line.
");
       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 <stdio.h>
#include "test_lib.h"
int main(void) {
          
   
        printf("========= start...
");
        test_print();
        return 0;
} 
编译命令如下(和链接静态库命令基本一样):
gcc test_bin1.c -L. -ltest -o test1 说明:编译的时候指定了libtest.so(上述编译好的动态库)
测试1:没有指定动态库路径,且没有将生成的动态库拷贝到系统路径下,测试结果如下图: Error:报错找不到动态库 libtest.so
没有打印main函数入口的内容,说明动态库加载是在软件启动时进行的。
测试2:指定动态库的路径后(也可以将动态库复制到系统目录下),测试结果如下图:
3、显示调用 (程序运行过程中加载动态库) 在代码中明确指出需要的动态库,不用在编译时指定。软件运行过程中,使用特定的函数来加载动态库,使用特定函数通过符号名来查找动态库内的函数或变量,并调用。
测试文件 test_bin2.c 内容如下:
#include <stdio.h>
#include <dlfcn.h>
#include "test_lib.h"
int main(void) {
          
   
        void * handle = NULL;
        void (* pFuc)(void) = NULL;  //函数指针
        printf("========= start...
");
        handle = dlopen("libtest.so", RTLD_NOW); //打开动态库
        if (handle == NULL) {
          
   
                printf("%s
", dlerror());
                return -1;
        }
        pFuc = dlsym(handle, "test_print");  // 查找需要使用的符号
        if ((pFuc != NULL) && (NULL == dlerror()) ) {
          
   
                pFuc();  // 调用动态库中的函数
        } else {
          
   
                printf("get test_print FUNC failed.
");
        }
        dlclose(handle);  // 卸载动态库
        return 0;
} 
编译命令如下:
gcc test_bin2.c -ldl -o test2 说明:不需要指定libtest.so,但是需要链接libdl.so(或者libdl.a)库,因为使用了libdl库中的函数
测试1:没有指定动态库路径,测试结果如下图: Error::报错找不到动态库 libtest.so
有打印main函数入口的内容,说明软件是可以启动的,动态库是在软件运行过程中加载的。
测试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
				       
			          下一篇:
			            模拟翻译软件(java) 
			          
			        
