Sto lavorando con un dongle USB Blue Giga BLE112. Forniscono un'API sotto forma di diverse intestazioni e amp; * File .c. Funziona tutto fuori dai callback. Ad esempio.
int main()
{
// defined in a "cmd_def.h" & implemented in "cmd_def.c"
ble_cmd_connection_get_status();
// read messages off the usb serial port forever
// At some point, we'll read the message that triggers the connection status event.
while (true) { readMessages(); }
}
// Call back that we implement
void ble_evt_connection_status(const struct ble_msg_connection_status_evt_t *msg)
{
// This is terrible because we could call the command from anywhere
// and have no idea what context the event is firing under
// with no way to pass any information into the callback except from global state.
if (msg->flags & connection_connected)
{
printf("WE'RE CONNECTED!);
}
}
Ci sono circa 100 coppie di questi Command
se responseEventCallback
s.
Ora, sto cercando di implementare una piccola applicazione per console C ++, ma ne sto facendo un uso estremamente difficile. Ho cercato di avvolgere questo comportamento in una classe C ++, ma sto fallendo miseramente. Ad ogni turno mi imbatto in problemi cercando di utilizzare questi callback per impostare lo stato in classe. (Ovviamente, non posso perché i callback sono statici e non posso accedere ai membri della classe.)
Era un'idea sbagliata? Ho pensato che se avessi potuto introdurre uno strato anti-corruzione OO, avrei potuto rendere più facile occuparmi dello stato globale e dell'inferno del callback in cui mi sono trovato.
Qualcuno ha qualche idea su come implementare in modo pulito questo tipo di API callback C in C ++? Sto guardando tutti questi richiami pensando che questo sarà un incubo da mantenere, ma non sono in grado di capire come avvolgere questi eventi di comando / risposta in una classe.
Sarebbe meglio semplicemente dimenticare le classi e implementarle come un "modulo" di funzioni?
Per riferimento, ecco un esempio di ciò che sto cercando di realizzare.
// nice clean OO api
bool scanning = false;
BLUEGIGA_API bool BlueGiga::IsConnected()
{
_isConnected = false;
ble_cmd_connection_get_status(0);
scanning = true;
while (scanning)
{
if (!ReadMessage())
{
return false;
}
}
return _isConnected;
}
// C callback that should not be part of my C++ api, nor can it be a member because C can't use C++ members as callbacks.
void ble_evt_connection_status(const struct ble_msg_connection_status_evt_t *msg)
{
// _isConnected isn't identified because we don't have a 'this' instance in here.
_isConnected = (msg->flags & connection_connected);
scanning = false;
}