C++ 使用不同参数计数调用函数
我正在反编译一个非常古老的游戏,我的目标是恢复100%的本地代码。因此,我需要尽可能地保留现有的体系结构(例如,仅仅使用C++ 使用不同参数计数调用函数,c++,function-pointers,C++,Function Pointers,我正在反编译一个非常古老的游戏,我的目标是恢复100%的本地代码。因此,我需要尽可能地保留现有的体系结构(例如,仅仅使用std::function并没有真正的帮助) 我有一组带有不同数量参数的静态函数。它们存储在如下结构中: struct ScriptFunction { const wchar_t* m_name; void* m_func; // ptr to specific function void* m_returnType; int m_arg
std::function
并没有真正的帮助)
我有一组带有不同数量参数的静态函数。它们存储在如下结构中:
struct ScriptFunction
{
const wchar_t* m_name;
void* m_func; // ptr to specific function
void* m_returnType;
int m_argCount;
};
ScriptFunction s_functions[206] = {
{L"AddMoveAroundDesire", &ScriptFunctions::AddMoveAroundDesire, &CScriptType::s_void, 2},
{L"AddDoNothingDesire", &ScriptFunctions::AddDoNothingDesire, &CScriptType::s_void, 2},
{L"AddAttackDesire", &ScriptFunctions::AddAttackDesire, &CScriptType::s_void, 3},
{L"AddAttackDesireEx", &ScriptFunctions::AddAttackDesireEx, &CScriptType::s_void, 4},
{L"AddGetItemDesire", &ScriptFunctions::AddGetItemDesire, &CScriptType::s_void, 2},
...
人口分布如下:
struct ScriptFunction
{
const wchar_t* m_name;
void* m_func; // ptr to specific function
void* m_returnType;
int m_argCount;
};
ScriptFunction s_functions[206] = {
{L"AddMoveAroundDesire", &ScriptFunctions::AddMoveAroundDesire, &CScriptType::s_void, 2},
{L"AddDoNothingDesire", &ScriptFunctions::AddDoNothingDesire, &CScriptType::s_void, 2},
{L"AddAttackDesire", &ScriptFunctions::AddAttackDesire, &CScriptType::s_void, 3},
{L"AddAttackDesireEx", &ScriptFunctions::AddAttackDesireEx, &CScriptType::s_void, 4},
{L"AddGetItemDesire", &ScriptFunctions::AddGetItemDesire, &CScriptType::s_void, 2},
...
那么,如何使用给定的m_argCount和void**参数调用ScriptFunction::m_func?我必须以某种方式在堆栈上推送参数并调用func调用,但我不知道
一些asm代码?瓦乌名单?但是如何在运行时填充它呢
UPD:调用程序如下所示
void CScriptAccessible::InvokeInternal(ScriptFunction* scriptFunc, void** args)
{
// here I have to push params from **args** to stack
// and somehow call ScriptFunction::m_func
// In assembly I could see pushes to stack in a loop (driven by
// ScriptFunction::m_argCount). But I'm wondering, whether it's
// possible to do in C++ (push args on stack and call function by just address)
}
在该语言中,只有
开关
/cast解决方案。这让编译器生成正确的调用约定:例如,在x86-64 Linux上,前几个参数在预定义寄存器中传递。(优化器可能会将不同的路径合并到跳转中,形成一种您期望的展开循环。)还要记住,仅在C/C++中,根本没有“堆栈”
顺便说一句,对函数使用
void*
也不能保证(因为它可以指向任何对象,但它们不是对象),尽管它通常是有效的(并且POSIX要求它用于dlsym
)。我为您删除了不需要的标记。如果你能解释,为什么它是有帮助的,请随意重新添加它,连同解释,并接受我的道歉。你是如何得到这些论点的?您想如何传递它们呢?ScriptFunctions
函数(ScriptFunctions::AddMoveAroundDesire
等)是静态的还是非静态的?每个脚本如何与提供的脚本函数一起工作?这些问题在选择调用/调用选项时非常重要,因为只有名为m_func
的成员是void*
和一组void**
参数。脚本函数::*是静态(自由)的。描述发生了变化。唯一的单一用法是在CScriptAccessible::InvokeInternal
内部。在assembly中,我可以看到循环中的堆栈推送(由ScriptFunction::m_argCount
驱动)。但我想知道,是否有可能在C++中(通过堆栈推栈和调用函数),你可能也想看看。我最终得到了<代码>开关/CASE / CAST到适当的FUNC原型< /Cord>解决方案。我认为,在最初的代码中,他们使用了asm,因为从二进制代码中可以清楚地看出这一点。