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

问题描述 投票:1回答:2

我想知道我是否可以在运行时“猜测”函数的返回类型。更具体地说,我使用dlopen加载动态库文件,然后通过调用dlsym我加载一个函数(让我们称之为foo)。函数foo已经从用户编写和编译(作为共享对象),有时可以返回double或者int。因此,用户可以将foo定义为:

extern "C" {
int foo(int a){

    return a+2;
}
}

要么:

extern "C" {
float foo(int a){

    return 1.0;
}
}

我有一个加载.so文件的编译代码(so文件是从用户编译的)。代码片段如下:

typedef int (*functionPointer)  (int ); //this sometimes is typedef int 
typedef float (*functionPointer)  (int ); //or typedef float
//can i "guess" the return type at runtime?
void *handle = dlopen(userLib.so, RTLD_LAZY);
functionPointer func = (functionPointer) dlsym(handle, "foo");
func(2);

我想知道这个typedef是否可以在运行时猜到。上面的代码片段已经完成编译,“doesent”知道给定共享对象中的函数是什么。

c++ c shared-objects
2个回答
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文件。


0
投票

我想知道我是否可以在运行时“猜测”函数的返回类型。

你不能。实际上,在某些ABI下,您可能需要知道返回类型以安全地调用函数,因为返回类型用于确定在堆栈上为返回值保留多少空间。

© www.soinside.com 2019 - 2024. All rights reserved.