I have a map of callbacks that pass information and execute various functions throughout code, very much like events in C# but in C++.
The map is defined as
std::map<std::string, std::function<void(uint8_t*)>> mCallbacks
It is passed by reference to all subprograms
Then each class binds its callbacks as such
mCallbacks["Status_Label"] = std::bind(&MenuHandler::LabelEditCallback, this, std::placeholders::_1);
Where
bool MenuHandler::LabelEditCallback(uint8_t * m_label_data)
{
int text_size = ((int*)m_label_text)[0];
char* v_text = (char*)&m_label_text[1];
}
And each event gets called from a different subprogram like this:
if (mCallbacks.find("Status_Label") != mCallbacks.end())
mCallbacks.at("Status_Label")((uint8_t*)selected_text);
This makes it easy to pass data and events around the program without making a mess of objects and references
As you can see, this is extremely unsafe, and converting from a uint8_t pointer to various data formats can easily lead to corrupted stack.
The problem is, I don't have a specific structure for callback arguments, some of them may be sending text data, others may be sending numbers.
My solution is to define structs that will be cast to void* when calling the event, and back in the callback function
Something like this (untested):
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;
};
And I would call it like this:
if (mCallbacks.find("Status_Label") != mCallbacks.end())
mCallbacks.at("Status_Label")((uint8_t*)Label_Callback_Data("Status_Label_name", "TEXT"))
But then how would I recover it here? If I dont know the exact size of the object?
bool MenuHandler::LabelEditCallback(uint8_t * m_label_data)
{
//?? Label_Callback_Data text_size = (Label_Callback_Data*)m_label_text
}
One solution is to use object with fixed size arrays, but there has to be a C++11 solution that is safe to use, maybe something using dynamic_pointer_casts?
Also, as a bonus question, how would I know if the object passed to the callback function is smaller in size than it is expecting? Is it possible to check this and just return a false from the callback function so the program doesn't crash?
Thank you, This code is not tested, so there may be logical mistakes I'm willing to correct per responses.