我想知道我是否可以在运行时“猜测”函数的返回类型。 更具体地说,我使用dlopen加载动态库文件,然后通过调用dlsym加载函数(我们称其为foo)。 函数foo是由用户(作为共享对象)编写和编译的,有时可以返回double或int。 因此,例如,用户可以将foo定义为:
- name: Install multiple rpm packages with its dependencies
yum:
name: "{{ item }}"
state: present
loop:
- rpm_package_dependency_1 (need not mention .rpm extension here)
- rpm_package_dependency_2
- rpm_package_1
- rpm_package_2
或:
extern "C" {
int foo(int a){
return a+2;
}
}
我有一个已编译的代码,可加载.so文件(so文件是从用户编译的)。该代码段如下:
extern "C" {
float foo(int a){
return 1.0;
}
}
我想知道是否可以在运行时猜测此typedef。上面的代码段已经准备好编译,“不再”知道给定共享库中的功能是什么。
答案 0 :(得分:0)
您要的内容在C语言中是不可能的,因为此类信息未保存在已编译的可执行文件中。如果您无权访问动态库的源代码或至少相应的头文件,则必须进行反汇编和分析以找出返回类型。
例如,您可以做的一件事是,将已知动态库哈希的列表放在一起,您知道其返回类型为int
。然后,您可以在加载库时计算其哈希值,并适当地转换函数指针:
typedef int (*functionPointerInt) (int );
typedef float (*functionPointerFloat) (int );
_Bool returnTypeIsInt = so_hash_in_table("userLib.so");
void *handle = dlopen("userLib.so", RTLD_LAZY);
if(returnTypeIsInt)
{
functionPointerInt func = (functionPointerInt) dlsym(handle, "foo");
func(2);
}
else
{
functionPointerFloat func = (functionPointerFloat) dlsym(handle, "foo");
func(2);
}
当然,这需要对.so文件进行预分析。
答案 1 :(得分:0)
我想知道我是否可以在运行时“猜测”函数的返回类型。
不,您不能。实际上,在某些ABI下,您可能需要知道返回类型才能完全安全地调用函数,因为返回类型用于确定在堆栈上为返回值保留多少空间。