用C语言构造函数调用
假设我有一个指向函数的指针(例如由用C语言构造函数调用,c,linux,gcc,function,arguments,C,Linux,Gcc,Function,Arguments,假设我有一个指向函数的指针(例如由dlsym()提供)和一个类型化参数的链表,我如何用这些参数构造一个C函数调用 例如: struct param { enum type { INT32, INT64, STRING, BOOL } type; union { int i32; long long i64; char *str; bool b; } value; struct param *next; }; int call_this(int (*function)(),
dlsym()
提供)和一个类型化参数的链表,我如何用这些参数构造一个C函数调用
例如:
struct param {
enum type { INT32, INT64, STRING, BOOL } type;
union { int i32; long long i64; char *str; bool b; } value;
struct param *next;
};
int call_this(int (*function)(), struct param *args)
{
int result;
/* magic here that calls function(), which has a prototype of
f(int, long long, char *, bool); , when args consist of a linked list of
INT32, INT64, STRING, BOOL types. */
return result;
}
操作系统是Linux。我希望该解决方案能够跨MIPS、PPC和x86(全部32位)体系结构进行移植,使用GCC作为编译器
谢谢 将参数解压为变量,然后调用函数
int a[10];
int n = 0;
while (args != NULL) {
if (args->type == INT64) {
#if __BIG_ENDIAN__
a[n++] = args->value.i64 >> 32;
a[n++] = args->value.i64 & 0xffffffff;
#else
a[n++] = args->value.i64 & 0xffffffff;
a[n++] = args->value.i64 >> 32;
#endif
} else { /* all other types are pushed as 32 bits parameters */
a[n++] = args->value.i32;
}
}
result = (*function)(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]);
您还必须检查
a
数组是否溢出。您可能需要使用。支持任意函数签名在标准C中是不可能的(至少我不知道有什么方法可以做到)。如果你需要这个,我会和你一起去
如果只需要支持有限数量的签名,则可以检查类型字段,并通过将无原型函数指针强制转换到正确的原型并自己提供正确的参数来适当地分派调用。强制转换函数指针是避免默认参数升级所必需的,但即使没有强制转换,您仍然必须手动对签名进行调度,才能访问正确的联合成员。通过使用您选择的脚本语言从签名列表生成C代码,该过程可以实现自动化。…准备好进行一些汇编黑客攻击,因为据我所知,纯C不能做到这一点……或者你可以使用方便的库。这是行不通的,因为
函数
没有正确的类型。函数
的类型是int(*)(
,在C中相当于int(*)(…)
。我还故意不回答解包的参数,因为这个问题更倾向于调用函数的魔力,而不是参数。你说得对。但是编译时无法知道arg0
、arg1
等的类型,因此这仍然不起作用。例如,如果您正在创建一种解释脚本语言,并且希望它支持在共享库中调用任意C函数,那么它非常有用。