[Libwebsockets] Binding member functions for protocol callbacks.

Mooki Moo mookimoo73 at gmail.com
Wed Apr 18 17:45:29 CEST 2018


Thank you for the reply, but it would seem that there is some
confusion here. I am aware of the void * user and it’s use and indeed
I make use of within my protocol. However this is about the actual
callback itself. As we know in C land this is done thus:

struct lws_protocols protocols[] = {
    { "http_only", callback_http, 0, 0 },
    { “ctrl-protocol", callback_protocol, 0, 0 },
    { NULL, NULL, 0, 0 }
};

int callback_protocol(struct lws * wsi, enum las_callback_reasons
reason, void * user, void * in, std::size_t len)
{
…
}

But as I am wrapping this in a class the callback_protocol(…) is now a
member function so I need to be able to set the callback field of the
protocols struct to the address of my member function and this is what
I am seeking assistance on.
--
Bill


On 18 April 2018 at 13:53, Eric Sessoms <esessoms at protonmail.com> wrote:
> std::bind creates a function object (of unspecified type) which is not at all the same thing as a function pointer.
>
> The protocols structure supports what you're trying to do by providing a "user" slot of type "void *" that gets passed to the callback.  You can use either a static function or a non-member function as the callback to cast the "user" data and relay into your member function.
>
>
> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
>
> On April 18, 2018 5:40 AM, Mooki Moo <mookimoo73 at gmail.com> wrote:
>
>>
>>
>> Hello,
>>
>> I am trying to create a C++ class to wrap my LWS Server in but I have
>>
>> encountered an issue where I am unable to bind member functions for
>>
>> the protocol callbacks. I have tried various approaches but nothing
>>
>> works, so I would appreciate it if someone could provide me with a
>>
>> pointer (no pun intended) as to how I can achieve this.
>>
>> From my header file I have:
>>
>> struct lws_protocols protocols[3] = {
>>
>> { "http_only", 0, 0, 0, 0, 0, 0 },
>>
>> { “ctrl-protocol", 0, sizeof(struct per_session_data),
>>
>> PAYLOAD_BUFFER, 0, 0, 0},
>>
>> { NULL, NULL, 0, 0, 0, 0, 0 }
>>
>> } ;
>>
>> And in my class file I have :
>>
>> protocols[0].callback = std::bind(&WEBSocket::defproto, this,
>>
>> std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
>>
>> std::placeholders::_4, std::placeholders::_5) ;
>>
>> protocols[1].callback = std::bind(&WEBSocket::protocol, this,
>>
>> std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
>>
>> std::placeholders::_4, std::placeholders::_5) ;
>>
>> But on compilation this produces :
>>
>> g++ -Wall -O2 -std=c++17 -c WEBSocket.cpp -DNDEBUG -I./
>>
>> -I/usr/include/ -I/usr/local/include/
>>
>> WEBSocket.cpp: In member function ‘const bool WEBSocket::init()’:
>>
>> WEBSocket.cpp:16:178: error: cannot convert ‘std::_Bind_helper<false,
>>
>> const int (WEBSocket::)(lws, lws_callback_reasons, void*, void*,
>>
>> long unsigned int), WEBSocket*, const std::_Placeholder<1>&, const
>>
>> std::_Placeholder<2>&, const std::_Placeholder<3>&, const
>>
>> std::_Placeholder<4>&, const std::_Placeholder<5>&>::type {aka
>>
>> std::_Bind<const int (WEBSocket::(WEBSocket, std::_Placeholder<1>,
>>
>> std::_Placeholder<2>, std::_Placeholder<3>, std::_Placeholder<4>,
>>
>> std::_Placeholder<5>))(lws*, lws_callback_reasons, void*, void*, long
>>
>> unsigned int)>}’ to ‘int ()(lws, lws_callback_reasons, void*, void*,
>>
>> size_t) {aka int ()(lws, lws_callback_reasons, void*, void*, long
>>
>> unsigned int)}’ in assignment
>>
>> protocols[0].callback = std::bind(&WEBSocket::defproto, this,
>>
>> std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
>>
>> std::placeholders::_4, std::placeholders::_5) ;
>>
>> ^
>>
>> WEBSocket.cpp:17:178: error: cannot convert ‘std::_Bind_helper<false,
>>
>> const int (WEBSocket::)(lws, lws_callback_reasons, void*, void*,
>>
>> long unsigned int), WEBSocket*, const std::_Placeholder<1>&, const
>>
>> std::_Placeholder<2>&, const std::_Placeholder<3>&, const
>>
>> std::_Placeholder<4>&, const std::_Placeholder<5>&>::type {aka
>>
>> std::_Bind<const int (WEBSocket::(WEBSocket, std::_Placeholder<1>,
>>
>> std::_Placeholder<2>, std::_Placeholder<3>, std::_Placeholder<4>,
>>
>> std::_Placeholder<5>))(lws*, lws_callback_reasons, void*, void*, long
>>
>> unsigned int)>}’ to ‘int ()(lws, lws_callback_reasons, void*, void*,
>>
>> size_t) {aka int ()(lws, lws_callback_reasons, void*, void*, long
>>
>> unsigned int)}’ in assignment
>>
>> protocols[1].callback = std::bind(&WEBSocket::protocol, this,
>>
>> std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
>>
>> std::placeholders::_4, std::placeholders::_5) ;
>>
>> ^
>>
>> make: *** [makefile:40: WEBSocket.o] Error
>>
>> However, my callback signatures match what is expected :
>>
>> const int WEBSocket::defproto(struct lws * wsi, enum
>>
>> lws_callback_reasons reason, void * user, void * in, std::size_t len)
>>
>> { return 0 ; }
>>
>> const int WEBSocket::protocol(struct lws * wsi, enum
>>
>> lws_callback_reasons reason, void * user, void * in, std::size_t len)
>>
>> {
>>
>>>>
>> }
>>
>>
>> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>>
>> Bill
>>
>> Libwebsockets mailing list
>>
>> Libwebsockets at ml.libwebsockets.org
>>
>> https://libwebsockets.org/mailman/listinfo/libwebsockets
>
>



More information about the Libwebsockets mailing list