Linux下C语言调用动态库函数时char *(*ver)()的作用是什么?
问题解答
原代码错误原因
dlsym函数的作用是返回动态库中指定符号的内存起始地址,返回值类型为void *,本身不携带任何类型信息- 第一版代码中直接将
show_version函数的地址赋值给char *类型的ver变量,相当于把函数地址当成了字符串的首地址,printf时会读取函数指令内存的内容作为字符串输出,自然得到错误结果
char *(*ver)()的含义
这是C语言标准的函数指针声明语法,按照C声明优先级从内到外拆解:
(*ver):表明ver是一个指针变量- 后面紧跟的
():表明这个指针指向的是一个函数 - 最开头的
char *:表明这个指向的函数的返回值类型是字符指针(即字符串)
整句含义就是:声明一个名为ver的函数指针,它指向无入参、返回值为char*类型的函数。如果要更严谨,建议声明为char *(*ver)(void),明确指定函数无入参,避免参数匹配错误。
为什么需要这样声明
dlsym返回的void*只是一个裸地址,编译器不知道这个地址对应的是数据还是函数,也不知道函数的调用规则、返回值类型。你通过函数指针的声明明确告诉编译器这个地址的类型信息:
- 调用
ver()时,编译器会按照函数调用规则去执行对应地址的代码 - 执行完成后会按照
char*类型来接收返回值,传给printf时就能正确输出字符串内容
拓展优化
为了提升代码可读性,可以用typedef给函数指针类型起别名,简化后续声明:
// 定义函数指针类型 typedef char* (*ShowVersionFunc)(); // 使用自定义类型声明变量 ShowVersionFunc ver = dlsym(dl, "show_version");
内容的提问来源于stack exchange,提问作者xieGieng
相关产品推荐
相关产品推荐

