Я программирую в очень статической среде и хотел бы как можно лучше обобщить проблему/код, сделать его чистым и избежать любого кода шаблона. Это мое дело; Я разрабатываю систему модификации, которая находится между программой и расширениями , где расширения будут перенаправлены на вызовы API. Когда моя модификация загружается программой, я получаю указатель на таблицу, состоящую целиком из указателей функций.Обобщение шаблона C++
struct APITable
{
void (*MouseClick)(int, int);
void (*MouseLeave)(bool);
int (*MouseRet)(float, int);
// And about a 200 more
// ......
};
В этой функции я установил обратный вызов функции/указатели, чтобы указать на мой собственный (т.е. apiTable->MouseClick = &MyMouseClick;
). Я пытаюсь расширить эту структуру (поскольку она позволяет только одну модификацию за раз) поддерживать несколько плагинов. Это делается путем загрузки дополнительных плагинов (в виде библиотек), а затем пересылает все обратные вызовы (например, MouseClick
) загруженным плагинам. Это пример;
void MyMouseClick(int x, int y)
{
bool blockOriginal = false;
// Iterate over all plugins
if(plugin_function_is_defined_pre)
blockOriginal = call_plugin_callback_pre(x, y);
if(!blockOriginal)
EngineMouseClick(x, y); // This is the programs "engine" function, which I have to call if I want normal execution flow
// Iterate over all plugins
if(plugin_function_is_defined_post)
call_plugin_callback_post(x, y);
}
Это очень упрощенная процедура, но я думаю, что она рассказывает все, что нужно сказать. Поскольку у меня более 200 функций, я бы не копировал и не вставлял весь этот шаблонный код. Обычной процедурой, вероятно, будет #define
, один для функций void
и один для функций с возвращаемым значением. Хотя это и работает, я определенно предпочел бы другое решение (что может быть невозможно, поскольку C++ является статически типизированным языком).
Дело в том, Я хочу обобщить эту процедуру чистым и эффективным способом, избегая любых шаблонов. Стоит упомянуть, что функции могут переопределить исходное значение возвращаемых функций, в обратных вызовах, которые не объявлены как void.
Так, чтобы лишить его до костей: Program->MyExtension->Plugins&Engine
ПРИМЕЧАНИЕ: Я не хотите использовать любой язык, но C++, и будет использовать C++ 11 функций, если это необходимо!
EDIT: В случае заинтересованности, это как моя модификация загружается программа:
extern "C" ModLoad(APITable * apiTable)
{
apiTable->MouseClick = &MyMouseClick;
apiTable->MouseLeave = &MyMouseLeave;
// And so on
// ...
}
«указатель на таблицу, состоящую целиком из указателей на функции» - это немного похоже на то, что вы пытаетесь переопределить C++ в C++ ... –
Также неясно, как ваш 1-й фрагмент кода относится ко второму фрагменту кода. –
@ Oli - что-то вроде Spring или другого каркаса IoC на C++, возможно –