mat*_*atg 3 c pointers function dynamic call
我想动态地调用C函数(例如,形成stdlib,math ...).这意味着我的C程序只知道指向随机函数(例如printf
)及其签名(编码为char数组:char *
,...)的指针.
我的目标是一个reflectCall函数,它获取一个指向函数(&printf
)的签名,一个签名(以某种方式编码在a中char[]
),参数作为一个long[]
(long
不是实际的数据类型,一个long值也可以表示一个double值,指针, ...).
因此,我的反射函数的签名如下所示:
long reflectCall(void *funcPointer, char[] types, long[] args)
Run Code Online (Sandbox Code Playgroud)
该函数应该对函数进行实际调用,*funcPointer
最后返回其结果.
结果,我无法创建指针指针; 比如这个:
int (*functionPtr)(int,int);
Run Code Online (Sandbox Code Playgroud)
任何人都可以给我一个提示如何解决这个问题或建议任何参考实现?
小智 7
它可以在纯C中完成,但它不是那么简单而且不那么快:
为要调用的所有函数创建包装函数,例如:
int WrapPrintf(const char* types,long* args,long* results)
{
// Function specific code, in this case you can call printf for each parameter
while(*types)
{
switch(*types){
case 'i':
printf("%d",(int)*args);
break;
case 'c':
printf("%c",(char)*args);
break;
// .. and so on
}
++types;
++args;
}
// Return number of filled results
return 0;
}
int WrapFoo(const char* types,long* args,long* results)
{
// ..function specific code..
return 0;
}
Run Code Online (Sandbox Code Playgroud)指向包装函数的指针:
typedef int (*TWrapper)(const char*,long*,long*);
Run Code Online (Sandbox Code Playgroud)为包装函数创建表结构:
struct STableItem{
const char *strName;
TWrapper pFunc;
};
Run Code Online (Sandbox Code Playgroud)创建一个表:
STableItem table[] = {
{"printf", &WrapPrintf},
{"foo", &WrapFoo},
{NULL, NULL}
};
Run Code Online (Sandbox Code Playgroud)创建接口以从表中调用任何函数(按名称搜索函数并调用它):
int DynamicCall(const char *func_name,const char* types,long* args,long* results)
{
int k;
for(k=0;table[k].strName != NULL;++k){
if(strcmp(func_name,table[k].strName) == 0){
return table[k].pFunc(types,args,results);
}
}
return -1;
}
Run Code Online (Sandbox Code Playgroud)最后拨打电话:
long args[] = {123,'b'};
long results[8]; // not nice but just for an example
int res_count = DynamicCall("printf","ic",(long*)args,(long*)results);
Run Code Online (Sandbox Code Playgroud)注意:使用哈希函数可以更快地进行名称搜索