2012-05-13 11 views
6

Sto utilizzando una libreria che ha callback come questo:Creare un oggetto callback in stile C orientato agli oggetti?

void onReceive (Lacewing::Server &Server, Lacewing::Server::Client &Client, 
       char * Data, int Size) { 
    /* callback body */ 
} 

Server.onReceive (onReceive); /* to register the handler */ 

Mi piacerebbe essere in grado di avvolgere questo in una classe che può decidere cosa fare quando riceve un pacchetto (pattern Observer).

Come posso farlo con callback in stile C? La libreria non definisce un'interfaccia da cui ereditare.

Grazie

risposta

2

Dal momento che si sta utilizzando liblacewing, ogni classe ha un membro void * Tag prevista per i dati utente:

/* class method */ 

void MyServer::onReceive (Lacewing::Server &Server, Lacewing::Server::Client &Client, 
      char * Data, int Size) 
{ 
    /* callback body - this is inside the class */ 
} 


/* global function wraps the class method */ 

void onReceive (Lacewing::Server &Server, Lacewing::Server::Client &Client, 
      char * Data, int Size) 
{ 
    ((MyServer *) Server.Tag)->onReceive (Server, Client, Data, Size); 
} 

poi:

Server.Tag = myServerInstance; /* set the class instance pointer */ 
Server.onReceive (::onReceive); /* register the global function */ 
+0

Grazie e grazie per questa fantastica libreria :) it per sapere se le classi Client Server funzionano su iOS? Se non lo fanno, ci sono piani per aggiungere supporto? – jmasterx

1

Se ho capito bene, si poteva fare 2 modi diversi.

Supponendo che questa struttura callback sta usando il parametro dei dati per consentire di passare i propri dati alla funzione di callback (un paradigma comune), si potrebbe fare così:

class MyProcessingClass 
{ 
public: 
    MyProcessingClass(); 
    virtual ~MyProcessingClass(); 

    // Do whatever processing in this method 
    virtual void onReceive(Lacewing::Server &Server, Lacewing::Server::Client &Client); 
} 

void onReceive (Lacewing::Server &Server, Lacewing::Server::Client &Client, 
       char * Data, int Size) 
{ 
    if (Data != NULL) 
    { 
     MyProcessingClass *handler = reinterpret_cast<MyProcessingClass *>(Data); 
     handler->onReceive(Server, Client); 
    } 
} 

Oppure, se il il puntatore dati è qualcosa che devi elaborare invece di un "puntatore dati utente", probabilmente dovresti usare un singleton, una sorta di variabile globale o qualcosa di simile. Nella mia esperienza, questo è un modo meno comune di utilizzare i callback e, si spera, non è quello con cui hai a che fare.

MyProcessingClass g_Processor; 

MyProcessingClass *GetProcessor() 
{ 
    return &g_Processor; // or some other way of getting your instance 
} 

void onReceive (Lacewing::Server &Server, Lacewing::Server::Client &Client, 
       char * Data, int Size) 
{ 
    MyProcessingClass *handler = GetProcessor(); 
    if (handler != NULL) 
    { 
     handler->onReceive(Server, Client); 
    } 
} 
+0

Sì, il secondo modo è esattamente quello che ho' Mi occupo di :( – jmasterx

+0

Quindi, il metodo Singleton funzionerà per voi o avete altri requisiti che ne impediscono l'uso? –

Problemi correlati