[Libwebsockets] How to pass a lws_callback_function from a c++ class

andy at warmcat.com andy at warmcat.com
Wed Mar 18 01:58:37 CET 2020



On March 18, 2020 12:35:25 AM UTC, Pranjali Chumbhale <pranjalic at safeai.ai> wrote:
>I do not have the option of using a static method.

Lws is C, the compiler is telling you C code doesn't know how to play c++ games with magically passing "this" object context when invoking the dynamic function ptr.  Static function pointers don't need that and are compatible with C.

You "don't have the option" to do what you're doing.  Use a static function pointer and explicitly store your dynamic object pointer somewhere, where depends on the object scope but there should be somewhere.  Eg in lws_protocols in your example

https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-protocols-plugins.h#n73-74

Likewise there are .opaque_user_data, .user and some accessors in many lws objects with user-code defined lifetime.  Put your c++ "this" in there.  You're dealing with a C library, it has to be dealt with as C.

>I was trying more of
>https://isocpp.org/wiki/faq/pointers-to-members#memfnptr-vs-fnptr

It doesn't mention C.  If it did, it'd tell you what Brice (and eg, libcurl docs) say.

-Andy

>Regards,
>Pranjali
>
>
>On Tue, Mar 17, 2020 at 5:31 PM Brice Hamon <brice at ydotm.com> wrote:
>
>> Use a static method.
>>
>> On Tue, Mar 17, 2020 at 8:25 PM Pranjali Chumbhale
><pranjalic at safeai.ai>
>> wrote:
>>
>>> Hello Team,
>>>
>>> I am trying to pass  a c++ class member function as a callback to
>>> protocols.
>>>
>>> Here is the relevant piece of code.
>>>
>>> This is how my callback function is declared.
>>> int ns::class_name::callback_ws( struct lws *wsi, enum
>>> lws_callback_reasons reason,
>>> void *user, void *in, size_t len);
>>>
>>>
>>> This is how I am using it to pass it to protocols:
>>> std::function<int(struct lws *wsi, enum lws_callback_reasons reason,
>void
>>> *user, void *in, size_t len)> callback_func;
>>>
>>> callback_func = std::bind(&ns::class_name::callback_ws,this,
>>> std::placeholders::_1, std::placeholders::_2,
>>> std::placeholders::_3, std::placeholders::_4,
>>> std::placeholders::_5);
>>>
>>> m_protocols[0].name = "named_protocol";
>>> m_protocols[0].callback = callback_func;
>>> m_protocols[0].per_session_data_size = 0;
>>> m_protocols[0].rx_buffer_size = m_max_data_size;
>>>
>>> // terminator - needed by libwebsocket
>>> m_protocols[1].name = NULL;
>>> m_protocols[1].callback = NULL;
>>> m_protocols[1].per_session_data_size = 0;
>>> m_protocols[1].rx_buffer_size = 0;
>>>
>>> I am getting the following error:
>>>
>>> error: cannot convert ‘std::function<int(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
>>>    m_protocols[0].callback  = callback_func;
>>>                               ^~~~~~~~~~~~~
>>> I do not understand when the return data type of callback function
>is
>>> int, why is it throwing error looking for  int(*).
>>>
>>> Regards,
>>> Pranjali
>>> _______________________________________________
>>> Libwebsockets mailing list
>>> Libwebsockets at ml.libwebsockets.org
>>> https://libwebsockets.org/mailman/listinfo/libwebsockets
>>>
>>


More information about the Libwebsockets mailing list