我想知道我是否可以在运行时“猜测”函数的返回类型。更具体地说,我使用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中是不可能的,因为此类信息未保存在已编译的可执行文件中。如果您无法访问动态库的源代码或至少相应的头文件,则必须对其进行反汇编和分析以确定返回类型。
例如,您可以做的一件事就是将已知的动态库哈希列表放在一起,您知道返回类型是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文件。
我想知道我是否可以在运行时“猜测”函数的返回类型。
你不能。实际上,在某些ABI下,您可能需要知道返回类型以安全地调用函数,因为返回类型用于确定在堆栈上为返回值保留多少空间。