今天同学问了个问题, 为什么包含了<dlfcn.h> 用dlopen 还提醒未定义
我拿源码来看了下
#include <stdlib.h>
#include <dlfcn.h>
#include "add.h"
#include <stdio.h>
typedef int(*P_FUNC)(int,int);
int main(){
void *handler = dlopen("libtext.so",RTLD_NOW);
P_FUNC add = dlsym(handler,"add");
P_FUNC sub = dlsym(handler,"sub");
//if(!sub) perror("sub dlsym"),exit(-1);
P_FUNC mul = dlsym(handler,"mul");
//if(!mul) perror("mul dlsym"),exit(-1);
show(30,'+',20);
printf("%d\n",add(30,20));
show(30,'-',20);
printf("%d\n",sub(30,20));
show(30,'*',20);
printf("%d\n",mul(30,20));
dlclose(handler);
return 0;
}
更改如下
typedef int(*P_FUNC)(int,int);
typedef void (*P_SHOW)(int,char,int); //new
int main(){
void *handler = dlopen("libtext.so",RTLD_NOW);if(!handler) perror("dlopen"),exit(-1);
P_FUNC add = (P_FUNC)dlsym(handler,"add");
if(!add) perror("add dlsym"),exit(-1);
P_FUNC sub = (P_FUNC)dlsym(handler,"sub");
if(!sub) perror("sub dlsym"),exit(-1);
P_FUNC mul = (P_FUNC)dlsym(handler,"mul");
if(!mul) perror("mul dlsym"),exit(-1);
P_SHOW show = (P_SHOW)dlsym(handler,"show"); //new
//if(!show) perror("show dlsym"),exit(-1);
show(30,'+',20);
printf("%d\n",add(30,20));
show(30,'-',20);
printf("%d\n",sub(30,20));
show(30,'*',20);
printf("%d\n",mul(30,20));
dlclose(handler);
return 0;
}
接下来 继续编译 gcc main.c -ldl 没想到遇到了段错误, 并且终端输出了 dlopen: Success
if (!handler) {
printf ("dlopen失败:%s\n", dlerror());
return -1;
}
编译 结果输出的是
dlopenʧ�ܣ�libtext.so: cannot open shared object file: No such file or directory
打开动态库失败............果断忘了配置环境变量.............但是可以肯定的是 perror() 不能 代替dlerror()功能 ,稍后套路他俩的区别,先导入环境变量
$export LIBRARY_PATH=$LIBRARY_PATH:.
$export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
编译 运行 成功.
接下来我去查了 perror() 和 dlerror()的区别.
原来对动态链接库有特定的dlerror函数返回错误信息.
dlerror()
包含头文件:
#include <dlfcn.h>
函数原型:
char *dlerror(void);
函数描述:
perror()
void perror(const char *s)
函数描述:
perror( ) 用来将上一个函数发生错误的原因输出到标准设备(stderr)。参数 s 所指的字符串会先打印出,后面再加上错误原因字符串。此错误原因依照全局变量errno 的值来决定要输出的字符串。
在库函数中有个errno变量,每个errno值对应着以字符串表示的错误类型。当你调用"某些"函数出错时,该函数已经重新设置了errno的值。perror函数只是将你输入的一些信息和现在的errno所对应的错误一起输出。from[
百度百科]