在运行时猜测函数的返回类型

时间:2019-04-11 22:56:22

标签: c++ c shared-objects

我想知道我是否可以在运行时“猜测”函数的返回类型。 更具体地说,我使用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。上面的代码段已经准备好编译,“不再”知道给定共享库中的功能是什么。

2 个答案:

答案 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下,您可能需要知道返回类型才能完全安全地调用函数,因为返回类型用于确定在堆栈上为返回值保留多少空间。