这有点难以解释,但我会尽我所能 . 我将提出问题,因为它适用于一种方法,但要知道这个解决方案应该足够通用,以适用于给定的任何可能的方法 . 考虑以下:
我有一个常规的旧全局方法:
void MyMethod( int a, int b )
{
cout << a << " , " << b << endl;
}
我有另一种方法是调用此方法 .
void Caller( void* method, void* data, int size )
{
// convert method to some function calling convention
// call the method here with the given data
}
这个调用者应该能够在内部调用任何方法,而不需要知道它需要多少参数以及它们的数据类型 . 所有它真正了解的方法是方法的地址和整个参数列表的大小(以字节为单位) .
简单地说,如何调用任意方法并将其传递给任意数量的数据,以便将其解释为参数?
基本上,如果不修改 MyMethod
,如何将 void* data
推入 Caller
中用作参数的寄存器?这可能吗?我不担心安全性或便携性 .
在调用 Caller
之前,我有一个void * 's that point to the data that can be passed to the internally called method. I'数组,我不确定这是否是解决此问题的最佳方法 .
我正在编写一个脚本系统,实质上可以从脚本中调用方法 . 因此,这些方法存储在查找表中,其中每个方法都有一个字符串名称,并且对于要调用的实际方法具有void * . 在执行时我知道方法需要多少参数以及参数是什么类型(当在查找表中给出方法时,类型被存储为元数据) . 这允许我将作为脚本中的参数的字符串值转换为它们实际应该的值(使用自定义转换系统) . 但转换器返回void *,因为你这样称它:
string s = "123456";
void* result = Converter::Convert( "string*", "int", &s );
我可以保证 result
中存储的值实际上是所请求类型的值(如果存在此类型对的转换器),但无法转换为此类型,因为类型名称仅作为字符串提供 . 这使得转换器具有灵活性,并且真正无关紧要 . 但它使处理它返回的值变得复杂 . 所以在脚本中我会像这样打个电话:
MyMethod( 111, 222 )
然后解析它,方法名称将用于查找方法地址,然后转换器将它找到的值转换为预期的数据类型,但将它们返回为 void*
. 然后调用Caller,传入方法地址,它已经转换的参数,一个字节数组,以及参数数据数组的大小,以字节为单位 . 在这一点上,我需要调用该方法并传递这些参数 . 同样,我无法修改它调用的现有方法 .
我已经研究过汇编来传递这些数据了,但似乎你必须让方法裸以直接在汇编中读取参数或者做其他事情,而且我以前从未在汇编中工作过 . 虽然如果解决方案在于装配,我可以学习一些 .
请不要暗示模棱两可;如果您需要更多上下文,我可以提供它 . 只是评论 . 对此,我真的非常感激 .
1 回答
稍微改变实现细节,这里是如何做你想要的
请注意,此处仅适用于具有void返回类型的全局函数 . 此解决方案还使用boost :: any,它可以存储任何类型,稍后您可以从中提取类型 . 因此,使用它注册您的功能 . 然后创建一个boost :: any向量,并将任意值放入向量中 . 然后查找函数名称,并在示例main中调用 .
如果您有任何疑问,请告诉我 .