Creating a C style callback object?

I am using a library with such callbacks:

void onReceive (Lacewing::Server &Server, Lacewing::Server::Client &Client, char * Data, int Size) { /* callback body */ } Server.onReceive (onReceive); /* to register the handler */ 

I would like to be able to wrap this in a class that can decide what to do when it receives a packet (observer pattern).

How can I do this using C style callbacks? The library does not define an interface for inheritance.

thanks

+6
source share
2 answers

Since you are using liblacewing, each class has a void * Tag member for user data:

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

then

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

If I understand you correctly, you can do this in two different ways.

Assuming this callback structure uses the Data parameter so that you can pass your own data to the callback function (general paradigm), you can do it like this:

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

Or, if the data pointer is what you need to handle instead of the "user data pointer", you probably have to use a singleton, some kind of global variable or the like. In my experience, this is a less common way to use callbacks, and hopefully this is not what you are dealing with.

 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 ); } } 
+1
source

Source: https://habr.com/ru/post/915622/


All Articles