【发布时间】:2013-12-29 22:55:18
【问题描述】:
我将提出问题,因为它适用于一种方法,但知道该解决方案应该足够通用以适用于给定的任何可能的方法。考虑以下几点:
我有一个常规的旧全局方法:
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* 数组,它指向可以传递给内部调用方法的数据。我不确定这是否是解决这个问题的最佳方法。
我正在编写一个脚本系统,本质上,它可以从脚本中调用方法。因此,这些方法存储在一个查找表中,其中每个方法都有一个字符串名称,并且对于要调用的实际方法有一个 void*。在执行时,我知道该方法需要多少个参数以及参数是什么类型(当方法在查找表中给出一个条目时,这些类型存储为元数据)。这允许我将作为脚本中参数的字符串值转换为它们实际应该的值(使用自定义转换系统)。但是转换器返回一个 void*,因为你这样称呼它:
string s = "123456";
void* result = Converter::Convert( "string*", "int", &s );
我可以保证result 中存储的值实际上是请求的类型(如果存在此类型对的转换器),但无法转换为此类型,因为类型名称仅提供为一个字符串。这使得转换器灵活并且真正类型无关紧要。但这使得处理它返回的值变得复杂。所以在脚本中我会这样调用:
MyMethod( 111, 222 )
然后将对其进行解析,方法名称将用于查找方法地址,然后转换器将找到的值转换为预期的数据类型,但将它们返回为void*。然后将调用 Caller,传入方法地址、它已转换的参数(作为字节数组)以及参数数据数组的大小(以字节为单位)。正是在这一点上,我需要调用该方法并传递这些参数。同样,我无法修改它正在调用的现有方法。
我已经研究过汇编以传递这些数据,但似乎您必须使方法裸露才能直接在汇编中读取参数或执行其他操作,而且我以前从未真正在汇编中工作过。虽然如果解决方案在于组装,我可以学习一些。
【问题讨论】:
-
是的,很抱歉没有这样标记它。
-
你知道
std::function和std::bind吗? -
如果你可以使用c++11,像std::function这样的东西有用吗?
-
为什么是程序集标签?
-
装配标签是因为我不确定装配是否会参与解决方案。我试图远离 STL/Boost,因为我正在编写这些组件作为更大系统的一部分,并且它是一种“除非你绝对必须”处理这些库的方法。
标签: c++ pointers c++11 methods