Я начал работу над системой ловушек / событий в C ++.Предполагается, что эта система обрабатывает все виды событий, о которых сообщают другие части приложения.
Проблема, с которой я столкнулся, связана с тем, как я хочу, чтобы она работала.Как правило, я хочу, чтобы вы вызывали определенную функцию со всеми аргументами, которые вы хотите передать, а затем эта функция обрабатывает вызов всех зарегистрированных обработчиков этого конкретного события, передавая им аргументы, извлекая их значения результата и возвращая ее.
Как правило, это должно выглядеть так:
CHookReturn* bInitializationStatus = Hook::Run("Initialize", gGame);
CHookReturn* bThinkSuccessful = Hook::Run("Think");
Однако я столкнулся с одной проблемой.Я настроил его таким образом, чтобы функция Run
в пространстве имен Hook, вызывающая функцию Run структуры CHookData_t, должна была передавать varargs.Я не мог найти другой путь.Вот как это закончилось:
union CHookReturn
{
const char* m_pszValue;
int m_iValue;
float m_flValue;
double m_dlValue;
bool m_bValue;
};
struct CHookData_t
{
virtual void Run(CHookReturn* ret, ...) = 0;
};
namespace Hook
{
std::unordered_map<const char*, std::unordered_map<const char*, CHookData_t*>> umHookList;
bool Add(const char*, const char*, CHookData_t*);
bool Exists(const char*, const char*);
bool Remove(const char*, const char*);
int Count(const char*);
CHookReturn* Run(const char*, ...);
};
Сегмент файла CPP функции Hook :: Run:
CHookReturn* Hook::Run(const char* eventName, ...)
{
// FIXME: Look into alternative execution.
// This code seems more like a workaround
// than what I originally wanted it to be.
int count = Hook::Count(eventName);
CHookReturn* returnValues = new CHookReturn[count];
int c = 0;
unordered_map<const char*, CHookData_t*>::iterator itr;
unordered_map<const char*, CHookData_t*> res;
res = umHookList.at(eventName);
va_list valist;
void* args;
va_copy(args, valist);
for (itr = res.begin(); itr != res.end(); itr++)
{
CHookReturn returnData;
itr->second->Run(&returnData, args);
returnValues[c] = returnData;
++c;
}
return returnValues;
}
Приведенный выше код вызывает два предупреждения, которые заставляют меня задаться вопросом, если этохорошая идея, чтобы выполнить это таким образом, а также есть ли какие-либо альтернативы, которые я должен рассмотреть.
Полученные предупреждения были:
Warning C6001 Using uninitialized memory 'valist'.
Warning C6386 Buffer overrun while writing to 'returnValues': the writable size is 'count*8' bytes, but '16' bytes might be written.
Есть ли лучший способ сделать это?