2012-05-13 26 views
6

używam biblioteki, która ma zwrotnych tak:Wyznaczanie obiektu wywołania zwrotnego w stylu C?

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

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

Chciałbym móc zawinąć to w klasie, które mogą zdecydować, co zrobić, gdy odbiera paczkę (wzorzec obserwatora).

Jak mogę to zrobić w przypadku zwrotów w stylu C? Biblioteka nie definiuje interfejsu do dziedziczenia.

Dzięki

Odpowiedz

2

Ponieważ używasz liblacewing, każda klasa ma człon void * Tag przewidzianej dla danych użytkownika:

/* 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); 
} 

następnie:

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

Dzięki i dziękuję za tę wspaniałą bibliotekę :) Do you happ pl wiedzieć, czy klasy serwera klienta działają w systemie iOS? Jeśli nie, czy masz zamiar dodać wsparcie? – jmasterx

1

Jeśli rozumiem zostanie poprawnie, można zrobić to 2 różne sposoby.

Zakładając, że struktura ta zwrotna jest za pomocą parametru danych, co pozwala przekazać własne dane do funkcji zwrotnej (wspólny paradygmat), można zrobić to tak:

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); 
    } 
} 

Lub, jeśli wskaźnik danych jest czymś, co musisz przetworzyć zamiast "wskaźnika danych użytkownika", prawdopodobnie użyjesz pojedynczej, jakiejś zmiennej globalnej lub podobnej. Z mojego doświadczenia wynika, że ​​jest to mniej popularny sposób korzystania z wywołań zwrotnych, i mam nadzieję, że nie jest to, z czym masz do czynienia.

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

Tak, drugim sposobem jest dokładnie to, co ja” m radzi sobie z :( – jmasterx

+0

Więc, czy metoda singleton będzie działała dla ciebie, czy masz jakieś inne wymagania, które uniemożliwiają jej użycie? –

Powiązane problemy