链接动态库的两种方式

方法一:通过gcc编译命令指定“-l+库名”来链接动态库

假设我编写了一个函数,函数体如下:

#include "stdio.h"

void test_a()
{
  printf("this is in test_a...\n");
}

在makefile中将如上函数封装成动态库的命令为:

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

通过执行make libtest.so,就能够得到动态库libtest.so。

当我想要在另外一个程序main.c中使用它时,需要在程序内声明:

extern void test_a();

同时,在MakeFile中进行链接:

VPATH=src include
CROSS := gcc
CFLAG := -L ./ -ltest -Wl,-rpath=./
main:main.o
	$(CROSS) obj/main.o $(CFLAG) -o main
main.o:main.c
	$(CROSS) -Wall -std=c99 -I include -c $< -o obj/main.o

这样就能够在main.c中运行libtest.so动态库函数中的test_a()函数。

方法二:通过dlopen来使用动态库

该方法使用动态库不需要加入链接动态库“-ltest”的指令,程序在运行的时候也会自动加载动态库,有点像fopen打开文件,当你需要这个动态库的时候,用dlopen打开它就好了。

完整代码

#include <stdio.h>
#include <dlfcn.h>  //dlopen需要的头文件

int main()
{	
    void *handle = dlopen("libtest.so", RTLD_LAZY); //RTLD_LAZY:延迟加载,什么时候真正使用的时候才加载
    if(handle == NULL)
    {
        printf("handle is NULL\n");
    }
    void (*test_a)();
    test_a = dlsym(handle, "test_a"); //参数1:动态库句柄,参数2:函数名
    if(test_a != NULL)
    {
        test_a();
    }
    else
    {
        printf("test_a is Null ptr\n");
    }
    dlclose(handle);
    
    return 0;
}

生成动态库的命令是一样的:

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

生成main执行程序的MakeFile如下:

VPATH=src include
CROSS := gcc
CFLAG := -L ./ -ldl -Wl,-rpath=./
main:main.o
	$(CROSS) obj/main.o $(CFLAG) -o main
main.o:main.c
	$(CROSS) -Wall -std=c99 -I include -c $< -o obj/main.o
libtest.so:test_a.c
	$(CROSS) $^ -fPIC -shared -o $@

.PHONY: clean
clean:
	rm -rf *.o obj/*.o *.a main

需要注意的是,dlopen函数去搜索动态库的路径是按照动态库搜索路径找的:

动态链接时、执行时搜索路径顺序:

1. 编译目标代码-L时指定的动态库搜索路径

2. 环境变量LD_LIBRARY_PATH指定的动态库搜索路径

3. 配置文件/etc/ld.so.conf中指定的动态库搜索路径

4. 默认的动态库搜索路径/lib

5. 默认的动态库搜索路径/usr/lib

而本程序中生成的动态库libtest.so是在根目录下的,同时我们在makefile中通过-Wl,-rpath=./指令将根目录加入了动态链接库的搜索路径,因此在main.c程序中我们不能写动态库的绝对路径,例如"/home/testcode/libtest.so",而应该直接写“dlopen("libtest.so", RTLD_LAZY)”,这样才能找到。

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值