У меня есть карта обратных вызовов, которые передают информацию и выполняют различные функции в коде, очень похоже на события в C #, но в C ++.
Карта определяется как
std::map<std::string, std::function<void(uint8_t*)>> mCallbacks
Передается по ссылке на все подпрограммы
Затем каждый класс связывает свои обратные вызовы как таковые
mCallbacks["Status_Label"] = std::bind(&MenuHandler::LabelEditCallback, this, std::placeholders::_1);
Где
bool MenuHandler::LabelEditCallback(uint8_t * m_label_data)
{
int text_size = ((int*)m_label_text)[0];
char* v_text = (char*)&m_label_text[1];
}
И каждое событие вызывается из другой подпрограммы, например:
if (mCallbacks.find("Status_Label") != mCallbacks.end())
mCallbacks.at("Status_Label")((uint8_t*)selected_text);
Это позволяет легко передавать данные и события по программе, не мешая объектам и ссылкам
Как видите, это крайне небезопасно, и преобразование из указателя uint8_t в различные форматы данных может легко привести к повреждению стека.
Проблема в том, что у меня нет конкретной структуры для аргументов обратного вызова, некоторые из них могут отправлять текстовые данные, другие могут отправлять номера.
Мое решение - определить структуры, которые будут преобразованы в void * при вызове события и обратно в функцию обратного вызова
Примерно так (не проверено):
struct Label_Callback_Data
{
Label_Callback_Data(std::string v_name, std::string v_text)
{
labelName = v_name;
labelText = v_text;
size_of = sizeof(this);
}
int size_of;
std::string labelName;
std::string labelText;
};
И я бы назвал это так:
if (mCallbacks.find("Status_Label") != mCallbacks.end())
mCallbacks.at("Status_Label")((uint8_t*)Label_Callback_Data("Status_Label_name", "TEXT"))
Но тогда как мне восстановить это здесь? Если я не знаю точный размер объекта?
bool MenuHandler::LabelEditCallback(uint8_t * m_label_data)
{
//?? Label_Callback_Data text_size = (Label_Callback_Data*)m_label_text
}
Одним из решений является использование объекта с массивами фиксированного размера, но должно быть решение C ++ 11, которое безопасно использовать, может быть что-то с использованием dynamic_pointer_casts?
Кроме того, в качестве дополнительного вопроса, как я узнаю, что объект, переданный в функцию обратного вызова, меньше по размеру, чем он ожидает? Можно ли проверить это и просто вернуть false из функции обратного вызова, чтобы программа не вылетала?
Спасибо,
Этот код не проверен, поэтому могут быть логические ошибки, которые я готов исправить в ответах.