Problem Exporting Beast To wxWidgets

Do you have a question about makefiles, a compiler or IDE you are using and need to know how to set it up for wxWidgets or why it doesn't compile but other IDE's do ? Post your questions here.
Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 125
Joined: Wed Oct 28, 2015 9:48 pm

Problem Exporting Beast To wxWidgets

Post by Everydaydiesel »

I wrote a console application that uses boost/beast which works good but now I need it to work inside a wxwidgets dialog app.
When I start adding it to my main dialog for wxwidgets I start getting crazy errors. Any help is greatly appreciated.


Code: Select all

void TestDialog::OnInit(wxInitDialogEvent& event)
{
    m_threadWebListener = std::thread(&TestDialog::StartWebListener);
}

// This function produces an HTTP response for the given request. The type of the response object depends on the
// contents of the request, so the interface requires the caller to pass a generic lambda for receiving the response.
template<class Body, class Allocator, class Send>
void TestDialog::handle_request(http::request<Body, http::basic_fields<Allocator>>&& req, Send&& send)
{
    auto const bad_request = [&req](boost::beast::string_view why)
    {
        http::response<http::string_body> res{http::status::bad_request, req.version()};
        res.set(http::field::server, BOOST_BEAST_VERSION_STRING);
        res.set(http::field::content_type, "text/html");
        res.keep_alive(req.keep_alive());
        res.body() = why.to_string();
        res.prepare_payload();
        return res;
    };

    // Make sure we can handle the method
    if(req.method() != http::verb::get && req.method() != http::verb::head)
        return send(bad_request("Unknown HTTP-method"));

    // Request path must be absolute and not contain "..".
    if( req.target().empty() || req.target()[0] != '/' || req.target().find("..") != boost::beast::string_view::npos)
        return send(bad_request("Illegal request-target"));

    std::string path = req.target().to_string();

    http::response<http::string_body> res;
    res.version(11);   // HTTP/1.1
    res.result(http::status::ok);
    res.set(http::field::server, "Beast");
    res.body() = "Hello, world!";
    res.prepare_payload();

    // Respond to HEAD request
    if(req.method() == http::verb::head)
    {
        http::response<http::empty_body> res{http::status::ok, req.version()};
        res.set(http::field::server, BOOST_BEAST_VERSION_STRING);
        res.set(http::field::content_type, "application/json"); // mime_type(path));
        //res.content_length(body.size());
        res.keep_alive(req.keep_alive());
        return send(std::move(res));
    }

    res.keep_alive(req.keep_alive());
    return send(std::move(res));
}

template<class Stream>
struct send_lambda
{
    Stream& stream_;
    bool& close_;
    boost::system::error_code& ec_;

    explicit
    send_lambda(
        Stream& stream,
        bool& close,
        boost::system::error_code& ec)
        : stream_(stream)
        , close_(close)
        , ec_(ec)
    {
    }

// Report a failure
void fail(boost::system::error_code ec, char const* what)
{
    std::cerr << what << ": " << ec.message() << "\n";
}

// This is the C++11 equivalent of a generic lambda.
// The function object is used to send an HTTP message.


    template<bool isRequest, class Body, class Fields>
    void operator()(http::message<isRequest, Body, Fields>&& msg) const
    {
        // Determine if we should close the connection after
        close_ = msg.need_eof();

        // We need the serializer here because the serializer requires
        // a non-const file_body, and the message oriented version of
        // http::write only works with const messages.
        http::serializer<isRequest, Body, Fields> sr{msg};
        http::write(stream_, sr, ec_);
    }
};

// Handles an HTTP server connection
void TestDialog::do_session(tcp::socket& socket, std::string const& doc_root)
{
    bool close = false;
    boost::system::error_code ec;

    // This buffer is required to persist across reads
    boost::beast::flat_buffer buffer;

    // This lambda is used to send messages
    send_lambda<tcp::socket> lambda{socket, close, ec};

    for(;;)
    {
        // Read a request
        http::request<http::string_body> req;
        http::read(socket, buffer, req, ec);

        if(ec == http::error::end_of_stream)
            break;

        if(ec)
            return fail(ec, "read");

        // Send the response
        handle_request(std::move(req), lambda);

        if(ec)
            return fail(ec, "write");

        if(close)
        {
            // This means we should close the connection, usually because
            // the response indicated the "Connection: close" semantic.
            break;
        }
    }

    // Send a TCP shutdown
    socket.shutdown(tcp::socket::shutdown_send, ec);
}

void TestDialog::StartWebListener()
{
    try
    {
        string sListeningIp = "127.0.0.1";
        string sListeningPort = "300";

        auto const address = boost::asio::ip::make_address(sListeningIp);
        auto const port = static_cast<unsigned short>(std::stoi(sListeningPort));
        //unsigned short port = 3030;
        //std::string const doc_root = "";

        // The io_context is required for all I/O
        boost::asio::io_context ioc{1};

        // The acceptor receives incoming connections
        tcp::acceptor acceptor{ioc, {address, port}};
        for(;;)
        {
            tcp::socket socket{ioc};    // receive new connection
            acceptor.accept(socket);    // Block until we get a connection

            // Launch the session, transferring ownership of the socket
            std::thread{std::bind(&TestDialog::do_session, std::move(socket), "")}.detach();
        }
    }
    catch (const std::exception& e)
    {
        std::cerr << "Error: " << e.what() << std::endl;
//        return EXIT_FAILURE;
    }
}

Code: Select all

||=== Build: Debug(compiler: GNU GCC Compiler) ===|
/usr/include/c++/5/functional||In instantiation of ‘struct std::_Bind_check_arity<void (TestDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&), boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char (&)[1]>’:|
/usr/include/c++/5/functional|1439|required from ‘struct std::_Bind_helper<false, void (TestDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&), boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char (&)[1]>’|
/usr/include/c++/5/functional|1462|  required by substitution of ‘template<class _Func, class ... _BoundArgs> typename std::_Bind_helper<std::__is_socketlike<_Func>::value, _Func, _BoundArgs ...>::type std::bind(_Func&&, _BoundArgs&& ...) [with _Func = void (TestDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&); _BoundArgs = {boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char (&)[1]}]’|
/path/MyDialogMain.cpp|269|required from here|
/usr/include/c++/5/functional|1426|error: static assertion failed: Wrong number of arguments for pointer-to-member|
/usr/include/c++/5/functional||In instantiation of ‘struct std::_Bind_check_arity<void (TestDialog::*)()>’:|
/usr/include/c++/5/functional|1538|required from ‘struct std::_Bind_simple_helper<void (TestDialog::*)()>’|
/usr/include/c++/5/functional|1552|  required by substitution of ‘template<class _Callable, class ... _Args> typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type std::__bind_simple(_Callable&&, _Args&& ...) [with _Callable = void (TestDialog::*)(); _Args = {}]’|
/usr/include/c++/5/thread|137|required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (TestDialog::*)(); _Args = {}]’|
/path/MyDialogMain.cpp|93|required from here|
/usr/include/c++/5/functional|1426|error: static assertion failed: Wrong number of arguments for pointer-to-member|
/usr/include/c++/5/functional||In instantiation of ‘struct std::_Bind_simple<std::_Mem_fn<void (TestDialog::*)()>()>’:|
/usr/include/c++/5/thread|137|required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (TestDialog::*)(); _Args = {}]’|
/path/MyDialogMain.cpp|93|required from here|
/usr/include/c++/5/functional|1505|error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void (TestDialog::*)()>()>’|
/usr/include/c++/5/functional|1526|error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void (TestDialog::*)()>()>’|
/usr/include/c++/5/functional||In instantiation of ‘struct std::_Bind_simple<std::_Bind<std::_Mem_fn<void (TestDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&)>(boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char*)>()>’:|
/usr/include/c++/5/thread|137|required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = std::_Bind<std::_Mem_fn<void (TestDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&)>(boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char*)>; _Args = {}]’|
/path/MyDialogMain.cpp|269|required from here|
/usr/include/c++/5/functional|1505|error: no type named ‘type’ in ‘class std::result_of<std::_Bind<std::_Mem_fn<void (TestDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&)>(boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char*)>()>’|
/usr/include/c++/5/functional|1526|error: no type named ‘type’ in ‘class std::result_of<std::_Bind<std::_Mem_fn<void (TestDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&)>(boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char*)>()>’|
||=== Build failed: 8 error(s), 13 warning(s) (0 minute(s), 3 second(s)) ===|
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7477
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Problem Exporting Beast To wxWidgets

Post by ONEEYEMAN »

Hi,
Did you do all the necessary #include?

Thank you.
Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 125
Joined: Wed Oct 28, 2015 9:48 pm

Re: Problem Exporting Beast To wxWidgets

Post by Everydaydiesel »

Hello and thank you for the reply.

I have these includes (same one as the console app that works)

Code: Select all

#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/beast/http/string_body.hpp>
#include <boost/config.hpp>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Problem Exporting Beast To wxWidgets

Post by doublemax »

Where do you include the wx headers? Before or after the others? Whichever it is, try shuffling the order of includes around.

Which C++ version do these boost libs require? Did you set the compiler flags accordingly?
Use the source, Luke!
Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 125
Joined: Wed Oct 28, 2015 9:48 pm

Re: Problem Exporting Beast To wxWidgets

Post by Everydaydiesel »

Hello, I rebuilt the entire project and it worked. Not sure what happened to the old one but it is working now.

Thanks to both of you for helping
Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 125
Joined: Wed Oct 28, 2015 9:48 pm

Re: Problem Exporting Beast To wxWidgets

Post by Everydaydiesel »

Now I see what is happening.

When I include them in the namespace it starts throwing errors.

Code: Select all

        void CreateWebListener();
        template<class Body, class Allocator, class Send>
        void handle_request(http::request<Body, http::basic_fields<Allocator>>&& req, Send&& send);
        void fail(boost::system::error_code ec, char const* what);
        void do_session(tcp::socket& socket, std::string const& doc_root);
this does not work (throws the same errors as the first post)
I tried switching the headers around as suggested but it didnt make any difference. Its only when I add TestDialog:: in front of the function that it starts erroring

Code: Select all

        void TestDialog::CreateWebListener();
        template<class Body, class Allocator, class Send>
        void TestDialog::handle_request(http::request<Body, http::basic_fields<Allocator>>&& req, Send&& send);
        void TestDialog::fail(boost::system::error_code ec, char const* what);
        void TestDialog::do_session(tcp::socket& socket, std::string const& doc_root);

I would just let it run without qualifying it with TestDialog:: but I cannot get the data to the gui

this code does not work

Code: Select all

template<class Body, class Allocator, class Send>
void handle_request(http::request<Body, http::basic_fields<Allocator>>&& req, Send&& send)
{
     TextCtrl1->AppendText("NewCurrentConditionsAvailable");
this is the error

Code: Select all

error: ‘TextCtrl1’ was not declared in this scope|
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4204
Joined: Sun Jan 03, 2010 5:45 pm

Re: Problem Exporting Beast To wxWidgets

Post by PB »

I believe that when you said "namespace", you meant class methods. I know nothing about Beast: Can you actually use non-static class methods and if you can, do you pass an instance of the wxWidgets class when calling/binding them?
Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 125
Joined: Wed Oct 28, 2015 9:48 pm

Re: Problem Exporting Beast To wxWidgets

Post by Everydaydiesel »

thank you for replying.

i dont see any in the list of documentation/examples
http://www.boost.org/doc/libs/1_66_0/li ... operations

do you?
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7477
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Problem Exporting Beast To wxWidgets

Post by ONEEYEMAN »

Hi,
Can you post the code in the .h file?
Or even better - post both complete *.cpp/*.h file. I seriously doubt it needs static functions...

Nothing on the page you linked says that it has a static function....

Thank you.
Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 125
Joined: Wed Oct 28, 2015 9:48 pm

Re: Problem Exporting Beast To wxWidgets

Post by Everydaydiesel »

Sure and thank you for helping

//Test_DialogMain.h

Code: Select all

#ifndef TEST_DIALOGMAIN_H
#define TEST_DIALOGMAIN_H

//(*Headers(Test_DialogDialog)
#include <wx/dialog.h>
#include <wx/button.h>
#include <wx/textctrl.h>
//*)

#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/beast/http/string_body.hpp>
#include <boost/config.hpp>
#include <thread>

using namespace std;
using tcp = boost::asio::ip::tcp;       // from <boost/asio/ip/tcp.hpp>
namespace http = boost::beast::http;    // from <boost/beast/http.hpp>

class Test_DialogDialog: public wxDialog
{
    public:

        Test_DialogDialog(wxWindow* parent,wxWindowID id = -1);
        virtual ~Test_DialogDialog();

    private:

        //(*Handlers(Test_DialogDialog)
        void OnQuit(wxCommandEvent& event);
        void OnAbout(wxCommandEvent& event);
        void OnInit(wxInitDialogEvent& event);
        void OnButton1Click(wxCommandEvent& event);
        //*)

        //(*Identifiers(Test_DialogDialog)
        static const long ID_BUTTON1;
        static const long ID_TEXTCTRL1;
        //*)

        //(*Declarations(Test_DialogDialog)
        wxButton* Button1;
        wxTextCtrl* TextCtrl1;
        //*)

        DECLARE_EVENT_TABLE()

        std::thread m_threadWebListener;


        void CreateWebListener();
        template<class Body, class Allocator, class Send>
        void handle_request(http::request<Body, http::basic_fields<Allocator>>&& req, Send&& send);
        void fail(boost::system::error_code ec, char const* what);
        void do_session(tcp::socket& socket, std::string const& doc_root);

};

#endif // TEST_DIALOGMAIN_H


Test_Dialog.cpp

Code: Select all

#include "Test_DialogMain.h"
#include <wx/msgdlg.h>

//(*InternalHeaders(Test_DialogDialog)
#include <wx/string.h>
#include <wx/intl.h>
//*)

//helper functions
enum wxbuildinfoformat {
    short_f, long_f };

wxString wxbuildinfo(wxbuildinfoformat format)
{
    wxString wxbuild(wxVERSION_STRING);

    if (format == long_f )
    {
#if defined(__WXMSW__)
        wxbuild << _T("-Windows");
#elif defined(__UNIX__)
        wxbuild << _T("-Linux");
#endif

#if wxUSE_UNICODE
        wxbuild << _T("-Unicode build");
#else
        wxbuild << _T("-ANSI build");
#endif // wxUSE_UNICODE
    }

    return wxbuild;
}

//(*IdInit(Test_DialogDialog)
const long Test_DialogDialog::ID_BUTTON1 = wxNewId();
const long Test_DialogDialog::ID_TEXTCTRL1 = wxNewId();
//*)

BEGIN_EVENT_TABLE(Test_DialogDialog,wxDialog)
    //(*EventTable(Test_DialogDialog)
    //*)
END_EVENT_TABLE()

Test_DialogDialog::Test_DialogDialog(wxWindow* parent,wxWindowID id)
{
    //(*Initialize(Test_DialogDialog)
    Create(parent, id, _("wxWidgets app"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE, _T("id"));
    Button1 = new wxButton(this, ID_BUTTON1, _("Label"), wxPoint(104,176), wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON1"));
    TextCtrl1 = new wxTextCtrl(this, ID_TEXTCTRL1, _("Text"), wxPoint(8,8), wxSize(328,152), wxTE_MULTILINE, wxDefaultValidator, _T("ID_TEXTCTRL1"));

    Connect(ID_BUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&Test_DialogDialog::OnButton1Click);
    Connect(wxID_ANY,wxEVT_INIT_DIALOG,(wxObjectEventFunction)&Test_DialogDialog::OnInit);
    //*)
}

Test_DialogDialog::~Test_DialogDialog()
{
    //(*Destroy(Test_DialogDialog)
    //*)

    if (m_threadWebListener.joinable())
        m_threadWebListener.join();
}

// This function produces an HTTP response for the given request. The type of the response object depends on the
// contents of the request, so the interface requires the caller to pass a generic lambda for receiving the response.
template<class Body, class Allocator, class Send>
void Test_DialogDialog::handle_request(http::request<Body, http::basic_fields<Allocator>>&& req, Send&& send)
{
    auto const bad_request = [&req](boost::beast::string_view why)
    {
        http::response<http::string_body> res{http::status::bad_request, req.version()};
        res.set(http::field::server, BOOST_BEAST_VERSION_STRING);
        res.set(http::field::content_type, "text/html");
        res.keep_alive(req.keep_alive());
        res.body() = why.to_string();
        res.prepare_payload();
        return res;
    };

    // Make sure we can handle the method
    if(req.method() != http::verb::get && req.method() != http::verb::head)
        return send(bad_request("Unknown HTTP-method"));

    // Request path must be absolute and not contain "..".
    if( req.target().empty() || req.target()[0] != '/' || req.target().find("..") != boost::beast::string_view::npos)
        return send(bad_request("Illegal request-target"));

    std::string path = req.target().to_string();

    http::response<http::string_body> res;
    res.version(11);   // HTTP/1.1
    res.result(http::status::ok);
    res.set(http::field::server, "Beast");
    
    res.body() = "Hello, world!";
    res.prepare_payload();


    // Respond to HEAD request
    if(req.method() == http::verb::head)
    {
        http::response<http::empty_body> res{http::status::ok, req.version()};
        res.set(http::field::server, BOOST_BEAST_VERSION_STRING);
        res.set(http::field::content_type, "application/json"); // mime_type(path));
        //res.content_length(body.size());
        res.keep_alive(req.keep_alive());
        return send(std::move(res));
    }

    res.keep_alive(req.keep_alive());
    return send(std::move(res));
}

// Report a failure
void Test_DialogDialog::fail(boost::system::error_code ec, char const* what)
{
//    std::cerr << what << ": " << ec.message() << "\n";
}

// This is the C++11 equivalent of a generic lambda.
// The function object is used to send an HTTP message.
template<class Stream>
struct send_lambda
{
    Stream& stream_;
    bool& close_;
    boost::system::error_code& ec_;

    explicit
    send_lambda(
        Stream& stream,
        bool& close,
        boost::system::error_code& ec)
        : stream_(stream)
        , close_(close)
        , ec_(ec)
    {
    }

    template<bool isRequest, class Body, class Fields>
    void operator()(http::message<isRequest, Body, Fields>&& msg) const
    {
        // Determine if we should close the connection after
        close_ = msg.need_eof();

        // We need the serializer here because the serializer requires
        // a non-const file_body, and the message oriented version of
        // http::write only works with const messages.
        http::serializer<isRequest, Body, Fields> sr{msg};
        http::write(stream_, sr, ec_);
    }
};

// Handles an HTTP server connection
void Test_DialogDialog::do_session(tcp::socket& socket, std::string const& doc_root)
{
    bool close = false;
    boost::system::error_code ec;

    // This buffer is required to persist across reads
    boost::beast::flat_buffer buffer;

    // This lambda is used to send messages
    send_lambda<tcp::socket> lambda{socket, close, ec};

    for(;;)
    {
        // Read a request
        http::request<http::string_body> req;
        http::read(socket, buffer, req, ec);

        if(ec == http::error::end_of_stream)
            break;

        if(ec)
            return fail(ec, "read");

        // Send the response
        handle_request(std::move(req), lambda);

        if(ec)
            return fail(ec, "write");

        if(close)
        {
            // This means we should close the connection, usually because
            // the response indicated the "Connection: close" semantic.
            break;
        }
    }

    // Send a TCP shutdown
    socket.shutdown(tcp::socket::shutdown_send, ec);
}

void Test_DialogDialog::CreateWebListener()
{
    try
    {
        string sListeningIp = "127.0.0.1";
        string sListeningPort = "301";

        auto const address = boost::asio::ip::make_address(sListeningIp);
        auto const port = static_cast<unsigned short>(std::stoi(sListeningPort));

        // The io_context is required for all I/O
        boost::asio::io_context ioc{1};

        // The acceptor receives incoming connections
        tcp::acceptor acceptor{ioc, {address, port}};
        for(;;)
        {
            tcp::socket socket{ioc};    // receive new connection
            acceptor.accept(socket);    // Block until we get a connection

            // Launch the session, transferring ownership of the socket
            std::thread{std::bind(&Test_DialogDialog::do_session, std::move(socket), "")}.detach();
        }
    }
    catch (const std::exception& e)
    {
        std::cerr << "Error: " << e.what() << std::endl;
//        return EXIT_FAILURE;
    }
}

void Test_DialogDialog::OnQuit(wxCommandEvent& event)
{
    Close();
}

void Test_DialogDialog::OnAbout(wxCommandEvent& event)
{
    wxString msg = wxbuildinfo(long_f);
    wxMessageBox(msg, _("Welcome to..."));
}

void Test_DialogDialog::OnInit(wxInitDialogEvent& event)
{
    m_threadWebListener = std::thread(CreateWebListener);
}

//errors

Code: Select all

||=== Build: Debug in Test Dialog (compiler: GNU GCC Compiler) ===|
/usr/include/c++/5/functional||In instantiation of ‘struct std::_Bind_check_arity<void (Test_DialogDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&), boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char (&)[1]>’:|
/usr/include/c++/5/functional|1439|required from ‘struct std::_Bind_helper<false, void (Test_DialogDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&), boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char (&)[1]>’|
/usr/include/c++/5/functional|1462|  required by substitution of ‘template<class _Func, class ... _BoundArgs> typename std::_Bind_helper<std::__is_socketlike<_Func>::value, _Func, _BoundArgs ...>::type std::bind(_Func&&, _BoundArgs&& ...) [with _Func = void (Test_DialogDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&); _BoundArgs = {boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char (&)[1]}]’|
Test Dialog/Test_DialogMain.cpp|248|required from here|
/usr/include/c++/5/functional|1426|error: static assertion failed: Wrong number of arguments for pointer-to-member|
Test Dialog/Test_DialogMain.cpp||In member function ‘void Test_DialogDialog::OnInit(wxInitDialogEvent&)’:|
Test Dialog/Test_DialogMain.cpp|271|error: invalid use of non-static member function|
/usr/include/c++/5/functional||In instantiation of ‘struct std::_Bind_simple<std::_Bind<std::_Mem_fn<void (Test_DialogDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&)>(boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char*)>()>’:|
/usr/include/c++/5/thread|137|required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = std::_Bind<std::_Mem_fn<void (Test_DialogDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&)>(boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char*)>; _Args = {}]’|
Test Dialog/Test_DialogMain.cpp|248|required from here|
/usr/include/c++/5/functional|1505|error: no type named ‘type’ in ‘class std::result_of<std::_Bind<std::_Mem_fn<void (Test_DialogDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&)>(boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char*)>()>’|
/usr/include/c++/5/functional|1526|error: no type named ‘type’ in ‘class std::result_of<std::_Bind<std::_Mem_fn<void (Test_DialogDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&)>(boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char*)>()>’|
||=== Build failed: 5 error(s), 6 warning(s) (0 minute(s), 2 second(s)) ===|

// build log

Code: Select all

-------------- Build: Debug in Test Dialog (compiler: GNU GCC Compiler)---------------

g++ -Wall -std=c++11 -I/usr/lib/x86_64-linux-gnu/wx/include/gtk2-unicode-3.0 -I/usr/include/wx-3.0 -D_FILE_OFFSET_BITS=64 -DWXUSINGDLL -D__WXGTK__ -pthread -g -I/home/user/libs/include/ -c "Test Dialog/Test_DialogMain.cpp" -o obj/Debug/Test_DialogMain.o
In file included from /home/user/libs/include/boost/system/error_code.hpp:22:0,
                 from /home/user/libs/include/boost/beast/core/error.hpp:14,
                 from /home/user/libs/include/boost/beast/core/detail/type_traits.hpp:13,
                 from /home/user/libs/include/boost/beast/core/type_traits.hpp:15,
                 from /home/user/libs/include/boost/beast/core/bind_handler.hpp:14,
                 from /home/user/libs/include/boost/beast/core.hpp:15,
                 from Test Dialog/Test_DialogMain.h:19,
                 from Test Dialog/Test_DialogMain.cpp:10:
/usr/include/c++/5/functional: In instantiation of ‘struct std::_Bind_check_arity<void (Test_DialogDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&), boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char (&)[1]>’:
/usr/include/c++/5/functional:1439:12:   required from ‘struct std::_Bind_helper<false, void (Test_DialogDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&), boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char (&)[1]>’
/usr/include/c++/5/functional:1462:5:   required by substitution of ‘template<class _Func, class ... _BoundArgs> typename std::_Bind_helper<std::__is_socketlike<_Func>::value, _Func, _BoundArgs ...>::type std::bind(_Func&&, _BoundArgs&& ...) [with _Func = void (Test_DialogDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&); _BoundArgs = {boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char (&)[1]}]’
Test Dialog/Test_DialogMain.cpp:248:88:   required from here
/usr/include/c++/5/functional:1426:7: error: static assertion failed: Wrong number of arguments for pointer-to-member
       static_assert(_Varargs::value
       ^
Test Dialog/Test_DialogMain.cpp: In member function ‘void Test_DialogDialog::OnInit(wxInitDialogEvent&)’:
Test Dialog/Test_DialogMain.cpp:271:56: error: invalid use of non-static member function
     m_threadWebListener = std::thread(CreateWebListener);
                                                        ^
In file included from /home/user/libs/include/boost/system/error_code.hpp:22:0,
                 from /home/user/libs/include/boost/beast/core/error.hpp:14,
                 from /home/user/libs/include/boost/beast/core/detail/type_traits.hpp:13,
                 from /home/user/libs/include/boost/beast/core/type_traits.hpp:15,
                 from /home/user/libs/include/boost/beast/core/bind_handler.hpp:14,
                 from /home/user/libs/include/boost/beast/core.hpp:15,
                 from Test Dialog/Test_DialogMain.h:19,
                 from Test Dialog/Test_DialogMain.cpp:10:
/usr/include/c++/5/functional: In instantiation of ‘struct std::_Bind_simple<std::_Bind<std::_Mem_fn<void (Test_DialogDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&)>(boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char*)>()>’:
/usr/include/c++/5/thread:137:59:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = std::_Bind<std::_Mem_fn<void (Test_DialogDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&)>(boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char*)>; _Args = {}]’
Test Dialog/Test_DialogMain.cpp:248:89:   required from here
/usr/include/c++/5/functional:1505:61: error: no type named ‘type’ in ‘class std::result_of<std::_Bind<std::_Mem_fn<void (Test_DialogDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&)>(boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char*)>()>’
       typedef typename result_of<_Callable(_Args...)>::type result_type;
                                                             ^
/usr/include/c++/5/functional:1526:9: error: no type named ‘type’ in ‘class std::result_of<std::_Bind<std::_Mem_fn<void (Test_DialogDialog::*)(boost::asio::basic_stream_socket<boost::asio::ip::tcp>&, const std::__cxx11::basic_string<char>&)>(boost::asio::basic_stream_socket<boost::asio::ip::tcp>, const char*)>()>’
         _M_invoke(_Index_tuple<_Indices...>)
         ^
Process terminated with status 1 (0 minute(s), 2 second(s))
5 error(s), 6 warning(s) (0 minute(s), 2 second(s))
Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 125
Joined: Wed Oct 28, 2015 9:48 pm

Re: Problem Exporting Beast To wxWidgets

Post by Everydaydiesel »

This is the line that seems to be giving me the trouble

Code: Select all

void Test_DialogDialog::OnInit(wxInitDialogEvent& event)
{
    m_threadWebListener = std::thread(CreateWebListener);   // invalid use of non-static member function
}
I also tried

m_threadWebListener = std::thread(CreateWebListener, this);

but it is still barking about invalid use of non-static member function
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7477
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Problem Exporting Beast To wxWidgets

Post by ONEEYEMAN »

Hi,
Can you post a working snippet of the console application?
It is written in C++11 right?

Thank you.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Problem Exporting Beast To wxWidgets

Post by doublemax »

Code: Select all

m_threadWebListener = std::thread(CreateWebListener);   // invalid use of non-static member function
The error message is clear, the method must be static.
Use the source, Luke!
Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 125
Joined: Wed Oct 28, 2015 9:48 pm

Re: Problem Exporting Beast To wxWidgets

Post by Everydaydiesel »

doublemax wrote:

Code: Select all

m_threadWebListener = std::thread(CreateWebListener);   // invalid use of non-static member function
The error message is clear, the method must be static.
Right but when I make them static, it does work but then I can't get the data from the static class to the gui
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Problem Exporting Beast To wxWidgets

Post by doublemax »

Right but when I make them static, it does work but then I can't get the data from the static class to the gui
This is usually solved by passing a pointer to a Test_DialogDialog instance into the function, which you can then use to access the member variables.

It should probably look something like this (untested)

Code: Select all

void Test_DialogDialog::CreateWebListener(Test_DialogDialog *self)
{
  // use self to access Test_DialogDialog members
}

void Test_DialogDialog::OnInit(wxInitDialogEvent& event)
{
    m_threadWebListener = std::thread(Test_DialogDialog::CreateWebListener, this);
}
Beware that you're *not* allowed to use GUI elements from inside secondary threads in wxWidgets.
Use the source, Luke!
Post Reply