dlopen、dlsym、dlclose学习总结

1.介绍

  在dlfcn.h头文件中,包含了dlopen,dlerror,dlsym,dlclose函数。函数原型如下:

       #include <dlfcn.h>
        //打开指定的动态库,返回的是该动态库的handle,在dlsym,dlclose中将继续使用。
       void *dlopen(const char *filename, int flag);
        //查看错误信息
       char *dlerror(void);
        //获得对应的函数或变量
       void *dlsym(void *handle, const char *symbol);
        //关闭打开的动态库
       int dlclose(void *handle);

2.示例

2.1 调用系统动态库

/*************************************************************************
    > File Name: foo.c
    > Author: Jay
    > Mail: jaytanfly@gmail.com 
    > Description:dlopen、dlsym、dlclose的学习使用,示例来自man dlopen,通过dlopen动态
	调用cos函数,并算出cos2.0
 ************************************************************************/

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

int main(int argc, char **argv)
{
   void *handle;
   double (*cosine)(double);
   char *error;

   handle = dlopen("libm.so", RTLD_LAZY);
   if (!handle) {
       fprintf(stderr, "%s\n", dlerror());
       exit(EXIT_FAILURE);
   }

   dlerror();    /* 清楚之前存在错误信息 */

   /*这里写成:cosine = (double (*)(double)) dlsym(handle, "cos");
   或许会更自然一些,但是C99标准规定从“void *”转换为未定义的函数指针。
   */

   *(void **) (&cosine) = dlsym(handle, "cos");

   if ((error = dlerror()) != NULL)  {
       fprintf(stderr, "%s\n", error);
       exit(EXIT_FAILURE);
   }
   /*打印cos2.0的值*/
   printf("%f\n", (*cosine)(2.0));
   dlclose(handle);
   exit(EXIT_SUCCESS);
}
/*
编译:
     gcc -rdynamic -o foo foo.c -ldl
运行:
    ./foo
输出:
    -0.416147
 */

2.2 调用自己编写的动态库

/*************************************************************************
    > File Name: hello.c
    > Author: Jay
    > Mail: jaytanfly@gmail.com 
    > Description:制作一个自己的动态链接库
 ************************************************************************/
#include <stdio.h>

char* name = "Jay";
int age = 25;

const char* get_name()
{
	//printf("This is in  Hello.c ");
	return name;
}

void print_name()
{
	printf("This is in  Hello.c, name is : %s\n",name);
	return;
}

int get_age()
{
	//printf("This is in  Hello.c ");
	return age;
}

void print_age()
{
	printf("This is in  Hello.c, age is : %d\n",age);
	return;
}

void set_age(int a)
{
	age = a;
}



/*************************************************************************
    > File Name: dlopen-test.c
    > Author: Jay
    > Mail: jaytanfly@gmail.com 
    > Description:调用hello.so
 ***********************************************************************/

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


int main(int argc, char** argv)
{
	int i = 0;
	void* handle;
	void (*printName)();
	void (*printAge)();
	void (*setAge)(int a);

	handle = dlopen("/动态库所在位置/hello.so",RTLD_LAZY);

	if(!handle)
	{
		printf("%s %d, NULL == handle\n", __FUNCTION__, __LINE__);
		return -1;
	}

	dlerror();
	//获取print_name函数
	*(void **) (&printName) = dlsym(handle, "print_name");

	if(!printName)
	{
		printf("%s %d, NULL == printName\n", __FUNCTION__, __LINE__);
		return -1;
	}
	(*printName)();
	//获取print_age函数
	*(void **) (&printAge) = dlsym(handle, "print_age");

	if(!printAge)
	{
		printf("%s %d, NULL == printAge\n", __FUNCTION__, __LINE__);
		return -1;
	}
	(*printAge)();
	//获取set_age函数
	*(void **) (&setAge) = dlsym(handle, "set_age");

	if(!setAge)
	{
		printf("%s %d, NULL == printAge\n", __FUNCTION__, __LINE__);
		return -1;
	}
	//设置age=30
	(*setAge)(30);
	//打印age
	(*printAge)();
	dlclose(handle);
	return 0;

}

编译:

    gcc -shared -o hello.so hello.c -fPIC

    gcc -o test dlopen-test.c -ldl

运行:

     ./test

输出:

    This is in  Hello.c, name is : Jay
    This is in  Hello.c, age is : 25
    This is in  Hello.c, age is : 30


3.总结

  动态打开链接库,可以随时更新相关的库,并且不用修改主函数, 利用动态链接库完成相关功能的添加和删除,大大提高了灵活性。

版权声明:本文为博主原创文章,未经博主允许不得转载。原文链接:https://blog.csdn.net/ta_tan

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值