2013-06-21 4 views
1

Я занимаюсь библиотекой обмена сообщениями в библиотеке websocket ++. Эта библиотека позволяет мне устанавливать собственные функции для управления сообщениями. Поскольку я не занимаюсь окончательным приложением, которое будет использовать мой код, мне нужно также разрешить моим пользователям устанавливать нужные функции для этих обработчиков.Тип для указателя функции, который будет использоваться в boost :: bind

Как это работает сейчас. Где-то есть класс socket (m_client), который имеет свою функцию set_handler, которая используется как следующий фрагмент.

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

, что я хотел бы сделать, это предоставить функцию, которая будет принимать в качестве параметра & MYFUNCTION так что пользователь просто называют как:

my_class.set_msg_handler(&myFunction); 

, а затем это будет декларация:

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

Но я не мог прояснить, что является правильным типом для моей функции, чтобы скомпилировать его. Или даже если это хороший подход к архивированию этого. Я прошел расширенный код, чтобы узнать, могу ли я получить подсказку ... но по мере того, как он заканчивает работу с шаблонами, это то, чего я еще не справляюсь.

Я знаю, что было бы проще заставить самого пользователя выполнить привязку и передать ее вывод, но m_client недоступен напрямую, и я хотел бы сохранить этот способ для инкапсуляции. И я полагаю, что это не обязательно сейчас, может быть, когда-нибудь мне это понадобится. Поэтому, предлагая учиться, я решил спросить об этом любым способом.

Я совершенно новый на C++ для этого уровня использования, а все указатели и обработчики функций и шаблоны немного меняют в моем реальном понимании. Я прочитал о применении связывания, но все примеры состоят в объявлении функции, а затем напрямую используют привязку.

Также искали аналогичный вопрос, но не нашли его, если он существует. И я не откажусь от того, что мой подход не самый лучший или совершенно неправильный, поэтому все рекомендации и рекомендации будут приветствоваться.

ответ

0

ОК, наконец, я заставляю его работать так, как я ожидал. Решение было довольно простым, просто проблема с моим опытом работы на C++.

Прежде всего в заголовке класса, который будет выполнять окончательное связывание, я объявил тип, объявляющий указатель на функцию со структурой, которую должен иметь message_handler. Способы обертки в других классах легко определить:

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

Мне потребовалось время, чтобы получить правильное объявление ...После этого, я объявил в соответствующем классе функцию, которая будет performint связывание:

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

Последняя обертка для этого на моем классе контроллера:

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

И там, где я хочу, я заявляю, что я реальный msg_handler, что очень просто можно будет отправлять только на стандартный вывод, что это 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); 
} 

И вот как вы передаете функции в качестве параметра другой functi сверху похоже. И у меня мое приложение работает.

Спасибо всем за ваши советы!

1

наддува с помощью шаблона может быть, вы должны попробовать что-то вроде

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

Но если вы хотите, чтобы заставить пользователя, чтобы дать какую-то функцию можно проверить для шаблонов специализаций.

Но bind примет практически любые указатели.

+0

ммм, но это не решает мою проблему, когда я знаю, что Т ... может сделать слишком сложный вопрос для глупой вещи ... – E1000i

+0

От cplusplus.com: Когда компилятор встречается с этим вызовом шаблона, он использует шаблон для автоматической генерации функции, заменяющей каждый вид T типом, переданным в качестве фактического параметра шаблона, а затем вызывает его. Этот процесс автоматически выполняется компилятором и невидим для программиста. Когда вы смотрите на определение bind, это функция шаблона. Но если вы хотите указать тип своей функции, это основной указатель на функцию на примере: void (ptr)() – Alexis

+0

yep, я только что открыл его и пытался заставить его работать. Thansk .. и о моем последнем комментарии ... – E1000i