Я ищу решение для динамического вызова виртуальной функции. Это означает поддержку вызовов функций со смещениями и динамическими типами во время выполнения.
Я работаю над плагином для игры (Counter-Strike: Source, если вы это знаете). Интерфейс плагина маловероятен, и поэтому вы не можете расширять его так, как хочет большинство людей. Чтобы реализовать лучший способ общения и манипулирования игрой, я поддерживаю вызов виртуальных функций. Например, класс CCSPlayer имеет следующие методы:
Offset Name
...
201 CCSPlayer::Ignite()
...
205 CCSPlayer::CommitSuicide(bool Blah)
...
250 CCSPlayer::SomeFunctionWith2Params(int A1, float A2)
Передав эти смещения и указатель на экземпляр этого класса моей текущей функции (см. Ниже), я могу вызвать следующие функции:
CBasePlayer *pPlayer = Players.Find("mike");
bool bResult = Call2<bool, int, float>(210 /* offset */, pPlayer, 20, 50.0f);
Я делаю это для вызова виртуальных функций, которые я не могу вызвать через обычную процедуру, потому что компилятор не знает структуру производного класса CCSPlayer.
А теперь я хочу добавить язык сценариев с динамическими вызовами виртуальных функций. Это означает, что сценаристы могут устанавливать количество параметров и их тип. Затем передаем указатель this и смещение функции, чтобы наконец выполнить ее. Это мои настоящие вопросы.
В настоящее время я могу только жестко их кодировать, используя шаблоны и создавая функцию для каждого количества параметров. Пример:
template<typename T, typename A, typename B> T Call2(int iOffset, void *pThis, A arg1, B arg2)
{
void **pVTable = *(void***)pThis;
void *pPointer = pVTable[_iOffset];
union
{
T (CVCallEmpty::*pCall)(A, B);
void *pAddress;
} Data;
Data.pAddress = pPointer;
return (reinterpret_cast<CVCallEmpty*>(*(void***)&pThis)->*Data.pCall)(arg1, arg2);
}
Теперь, есть ли возможность поддерживать динамические вызовы?