Reputation: 896
I have the following code using Boost ASIO to setup a TCP client. Here is my code adapted from the Boost doc's chat example.
class AsioCommunicationService {
AsioCommunicationService::AsioCommunicationService(
boost::asio::io_service& io_service,
tcp::resolver::iterator endpoint_iterator)
: io_service_(io_service),
socket_(io_service)
{
tcp::endpoint endpoint = *endpoint_iterator;
socket_.async_connect(endpoint,
boost::bind(&AsioCommunicationService::handle_connect, this,
boost::asio::placeholders::error, ++endpoint_iterator));
}
void AsioCommunicationService::handle_connect(const boost::system::error_code& error,
tcp::resolver::iterator endpoint_iterator)
{
if (!error)
{
boost::asio::async_read(socket_,
boost::asio::buffer(read_msg_.data(), LampMessage::header_length),
boost::bind(&AsioCommunicationService::handle_read_header, this,
boost::asio::placeholders::error));
}
}
}
class Connection
{
//init io_service, query, resolve, iterator here
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query(host, service);
boost::asio::ip::tcp::resolver::iterator endpoint_iterator =
resolver.resolve(query);
m_session = std::shared_ptr<AsioCommunicationService>(
new AsioCommunicationService(io_service, iterator));
//start new thread for io_service.run --> GOT AN ERROR when include boost/thread.hpp
boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));
//this synchronous command would work, but it's blocking the program. I don't want that.
//io_service.run();
}
Of course, I needed to include boost/thread to make the declaration to variable t in class Connection works. But when I did so, I got this error
#include <boost/thread.hpp>
//ERROR: In function ‘boost::thread&& boost::move(boost::thread&&)’:
///usr/include/boost/thread/detail/thread.hpp:349:16: error: invalid initialization of reference of type ‘boost::thread&&’ from expression of type ‘boost::thread’
//In file included from /usr/include/boost/thread/detail/thread_heap_alloc.hpp:17:0,
// from /usr/include/boost/thread/detail/thread.hpp:13,
// from /usr/include/boost/thread/thread.hpp:22,
// from /usr/include/boost/thread.hpp:13,
// from /home/son/dev/logistics/src/frameworks/networkService/NetworkConnection.cpp:13:
///usr/include/boost/thread/pthread/thread_heap_alloc.hpp: In function ‘T* boost::detail::heap_new(A1&&) [with T = boost::detail::thread_data<void (*)()>, A1 = void (*&)()]’:
///usr/include/boost/thread/detail/thread.hpp:130:95: instantiated from here
///usr/include/boost/thread/pthread/thread_heap_alloc.hpp:24:47: error: cannot bind ‘void (*)()’ lvalue to ‘void (*&&)()’
///usr/include/boost/thread/detail/thread.hpp:43:13: error: initializing argument 1 of ‘boost::detail::thread_data<F>::thread_data(F&&) [with F = void (*)()]’
It would compile and work if I remove the include to boost/thread.hpp, and replace the declaration to t by a simple call to io_service.run(); I'm wondering if this compilation error has to do with boost version. I'm using Boost ASIO 1.42, Ubuntu 11.04 and Eclipse if those are of any help. Thank you in advance.
Upvotes: 1
Views: 3779
Reputation: 896
After much exploration, following @MvG suggestion, I successfully compiled and linked my simple program by doing the following:
Dynamic:
default: test
test.o: test.cpp
g++-4.5 -std=c++0x -I /home/son/boost_1_50/include/ -c test.cpp
test: test.o
g++-4.5 -std=c++0x -L /home/son/boost_1_50/lib/ test.o -lboost_thread -lboost_system -lboost_chrono -pthread -o test
run: test
LD_LIBRARY_PATH=/home/son/boost_1_50/lib/ ./test
Static:
default: test
test.o: test.cpp
g++-4.5 -std=c++0x -I /home/son/boost_1_50/include/ -c test.cpp
test: test.o
g++-4.5 -std=c++0x -L /home/son/boost_1_50/lib/ test.o -static -lboost_thread -lboost_system -lboost_chrono -pthread -o test
run: test
./test
The test.cpp file is as follows.
#include <boost/thread.hpp>
#include <stdio.h>
int main()
{
printf("boost thread tested by son\n");
boost::thread t;
return 0;
}
That's it. I'm having difficulties compiling this with CMake but that's another problem.
Upvotes: 0
Reputation: 60858
I wrote a single file containing a single include directive:
#include <boost/thread.hpp>
g++-4.5.4 -std=c++0x -I /usr/include/boost-1_42 -c
gave the errors you mention.g++-4.6.3 -std=c++0x -I /usr/include/boost-1_42 -c
the sameg++-4.7.1 -std=c++0x -I /usr/include/boost-1_42 -c
gave even more errorsg++-4.7.1 -std=c++0x -I /usr/include/boost-1_49 -c
has not a single errorg++-4.6.3
and g++-4.5.4
also work without error using boost 1.49So I'd really suggest you use a more recent version of boost for this. You don't have to install it system-wide, but instead can install it for a single user. So you are not dependent on ubuntu packages.
To manually install boost, I suggest you follow the Getting Started on Unix Variants guide:
boost_1_50_0.tar.bz2
to some temporary source directory and cd
into that./bootstrap.sh --prefix=${HOME}/boost_1_50 && ./b2 install
-I ${HOME}/boost_1_50
to get correct headers${HOME}/boost_1_50/lib/libboost_thread.a
as an argument when linking your applicationUsing the static libboost_thread.a
as opposed to the dynamic libbtoost_thread.so
will ensure that you don't have to worry about locating libraries to launch your application. Everything from boost which you need will be included in your main binary.
Upvotes: 3
Reputation: 896
Following the line of reasoning of @MvG of C++11 standard, I did some research. It seems that it's a problem of coordination between gcc and boost provided with Ubuntu Natty, which used -std=c++0x and libboost1.42, respectively.
There's no solution for it, but I used this workaround: commenting out # define BOOST_HAS_RVALUE_REFS
in /usr/include/boost/config/compiler/gcc.hpp as follows.
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
// C++0x features are only enabled when -std=c++0x or -std=gnu++0x are
// passed on the command line, which in turn defines
// __GXX_EXPERIMENTAL_CXX0X__.
# define BOOST_HAS_DECLTYPE
//# define BOOST_HAS_RVALUE_REFS
# define BOOST_HAS_STATIC_ASSERT
# define BOOST_HAS_VARIADIC_TMPL
#else
My code compiles like magic now:) Thanks @MvC.
Upvotes: 1