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.

有帮助吗?

解决方案 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!

其他提示

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top