2012-04-09 40 views
1

我知道这是一个坏主意的原因,并且我也知道这是创建C++模板的原因,但我在C中为了好玩而做了它,学习。在运行时用任意堆栈数据手动调用C函数

我正在将Python嵌入到我的应用程序中,并且希望能够在应用程序运行时注册某些具有任意类型的C函数。正因为如此,它们的指针才被存储(作为一个简单的void *)。

随着一些基本的宏趣味,我得到了所有关于这些函数的信息,并存储了它们 - 函数指针,返回值的大小(如果它是void),参数的数量和每个他们的大小。

所以我被卡在最后阶段 - 这是函数指针与相应数据的实际调用。我相当肯定这种事情应该是可能的(我在我自己的时间里导致了堆栈错误),但我想知道是否有更合理的方法来做到这一点。

我想,理想的情况是这个样子:

void call_function(void* function, void* return, void* arg_data, int arg_data_size); 

难道这样的事情存在?

感谢

+1

这绝对没有平台无关的机制。你可以得到最接近的是可变参数函数。 – 2012-04-09 20:30:00

+0

你可以做到,但它会依赖于机器。在你选择的操作系统,编译器和体系结构上查看C调用约定。 (例如,unix上的x86 gcc的cdecl,amd64 unix的sysv-amd64,win32 x86的stdcall ...) – 2012-04-09 22:51:41

+0

@ConradMeyer谢谢!现在深入了解一下,即使是ASM也会变得复杂。也许我已经咬掉了比我可以在这里嚼... – 2012-04-10 15:43:14

回答

1

可以声明一个函数指针void* (*f) (void*);指向,需要一个void*参数,返回void*返回值的函数 - 你可以把这个在call_function第一个参数。

然后调用call_function为:

void* function(void*); 
ret_type ret; 
arg_type arg_data; 
call_function(&function, (void*)&ret, (void*)&arg_data, sizeof(arg_data)); 

其中arg_type是要内functionret_type使用实际的参数类型的实际类型的function的返回值。

注意:您也可能需要指定返回值类型的大小。

注意:这将适用于任何一个参数的函数。该解决方案可以扩展为function中固定/已知数量的参数,但不处理未知数量的参数。

注意:命名第二个参数return是不允许的,因为return是关键字。

+0

这也不处理多个输入参数。 – 2012-04-09 20:46:43

+0

我不确定我是否明白你的意思。我的想象函数“call_function”实际上并不存在。否则,我已经完成了。 – 2012-04-09 20:48:02

+0

@OliCharlesworth - 从我的问题来看,OP不想处理任意数量的参数 – Attila 2012-04-09 20:48:33