Question

I'm doing a messaging library around websocket++ library. This library allows me to set my own functions for manage the messages. As I am not doing the final application that will use my code I need to allow also to my users to set their desired functions for this handlers.

This is how it works now. Somewhere there is the socket(m_client) class that has his set_handler function that is used like the following snippet.

m_client.set_message_handler(bind(&myFunction,&m_client,_1,_2));

what i would like to do is provide a function that will take as parameter &myFunction so the user just call like:

my_class.set_msg_handler(&myFunction);

and then this will be the declaration:

void set_msg_handler(<type> myfunction){
    m_client.set_message_handler(bind(myFunction,&m_client,_1,_2));
}

But I could not make clear which is the correct type for myfunction in order to make it compile. Or if even this is a good approach to archive this. I went through boost code to see if i could get some hint... but as it ends working with templates, thats something that i don't manage yet.

I know it could be simpler to make the user itself do the bind and pass down its output, but m_client is not accessible directly and i would like to keep that way for encapsulation proposes. And I imagine that is not strictly necessary now, maybe some day I will need it anyway. So in the propose of learning i decided to ask it any way.

I'm quite new at C++ for this level of usage and the whole function pointers and handlers and templates scape a little to my actual understanding. I read about bind usage but all the examples consist on declaring a function and then using bind directly.

Also searched for a similar question, but didn't found it if it exist. And I will not discard that my approach is not the best or completely wrong, so all advises and recommendations will be welcome.

Was it helpful?

Solution 2

OK, finally I make it work as I was expecting. The solution was pretty simple, just a problem about my experience in c++.

First of all on the header of the class that will be performing the final bind I had declared a type declaring a function pointer with the structure that a message_handler must have. It will be easy to define the wrapper methods in oder classes:

typedef void (*msg_handler_ptr)(client*,connection_hdl,message_ptr);

It took me time to get the correct declaration... Once done, I have declared in the corresponding class the function that will be performint the binding:

 void set_msg_handler(msg_handler_ptr myfunction){
    using websocketpp::lib::placeholders::_1;
    using websocketpp::lib::placeholders::_2;
    using websocketpp::lib::bind;
    m_client.set_message_handler(bind(myfunction,&m_client,::_1,::_2));
} 

Last the wrapper for that on my controller class:

#include "mysocket_class.h"
void mycontroller::set_msg_handler(msg_handler_ptr myfunction)
{
    c.set_msg_handler(myfunction);
}

And wherever I want I declare my real msg_handler that to be very simple it will only send to standard output what it recieves:

void on_message(client* c, websocketpp::connection_hdl hdl, message_ptr msg) 
{
    client::connection_ptr con = c->get_con_from_hdl(hdl);
    std::cout << "Recived " << msg->get_payload() << std::endl;
}

int main(int argc, char* argv[]) {
    mycontroller c();
    c.set_msg_handler(&on_message);
}

And that's how you pass a function as a parameter of another function seems. And i have my app up an running.

Thanks you all for your hints!

OTHER TIPS

boost is using template maybe you should try something like

template <typename T>
void set_msg_handler(T myfunction){
    m_client.set_message_handler(bind(myFunction,&m_client,_1,_2));
}

But if you want to force the user to give some kind of function you can check for templates specializations.

But bind will accept almost any kind of pointers.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top