I am currently expiriencing a "bad function call" error in my code that I am not able to solve. Apparently the callback that I pass by const reference to the TcpConnection is null/not valid anymore when the TcpConnection::start() method is called.
For simplicitly, I posted a reduced minimal example below that does not contain the full code. If this is not enough to track down the problem I can edit my question and post the rest of the code as well.
I am by far no C++ expert so be patient with me :)
typedef std::function<void()> TcpMessageCallback;
class TcpConnection : public std::enable_shared_from_this<TcpConnection> {
public:
typedef std::shared_ptr<TcpConnection> pointer;
static pointer create(boost::asio::io_context &io_context, const TcpMessageCallback &cb) {
return pointer(new TcpConnection(io_context, cb));
}
tcp::socket &socket() {
return socket_;
}
void start() {
onDataCallback(); // <---- ***Error happens here***
}
private:
TcpConnection(boost::asio::io_context &io_context, const TcpMessageCallback &cb)
: socket_(io_context), onDataCallback(cb){};
tcp::socket socket_;
const TcpMessageCallback &onDataCallback;
};
class TcpServer {
public:
explicit TcpServer(boost::asio::io_context &context, const TcpMessageCallback &cb) :
io_context(context),
acceptor(context, tcp::endpoint(tcp::v4(), TCP_PORT_NUMBER)),
onDataReceivedCb(cb) {
start_accept();
}
private:
void start_accept() {
tcpConnection = TcpConnection::create(io_context, onDataReceivedCb);
auto onAcceptCb = [objPtr = this](auto error) {
objPtr->handle_accept(error);
};
acceptor.async_accept(tcpConnection->socket(), onAcceptCb);
}
void handle_accept(const boost::system::error_code &error) {
if (!acceptor.is_open())
{
return;
}
if (!error) {
tcpConnection->start();
}
start_accept();
}
boost::asio::io_context &io_context;
tcp::acceptor acceptor;
TcpConnection::pointer tcpConnection;
const TcpMessageCallback &onDataReceivedCb;
};
And then I would use it by starting the TcpServer with my own passed lambda function.
//... define context
auto server = TcpServer(io_context, []{ /*...*/});
io_context.run()
However when a new connection arrives the error happens at the TcpConnection::start() already where the onDataReceived callback somehow does not have a (or has an deleted?) function reference. It works when I pass the callback by value.
What could be the reason for this and how do I solve it?