Posts

Handy archive of boost binaries for Windows / Visual Studio

Every now and again I have to work on an old software project that may use an older version of the boost libraries. Well if like me, you occasionally find that you are missing some boost .lib file or other binary then have a look at this very handy archive of the boost windows binaries maintained by Thomas Kent:

http://boost.teeks99.com/

Thanks Thomas, very handy!

boost_software_library

C++ thread safe blocking queue using boost

In Software Engineering some patterns reoccur only every few years. The blocking queue pattern is on such for me. Here is a great article on an implementation of a thread-safe blocking queue that uses boost for synchronisation:

http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html

I implemented something like this some years ago (without the benefit of boost etc.) and now I need one again and I want to make it bang-up-to-date wrt. C++11 and boost etc., so this article is a real bonus, much thanks to Anthony Williams!

Write jpeg with header comment – boost generic image library (gil)

I had to hack the living daylights out of something today, and although I am not proud of it, needs must where the devil drives!

I was using the boost generic image library (gil) for managing some camera images and using jpeg_write_view() for saving them as JPEGs. A requirement emerged to insert a comment into the header of the saved images, but the gil does not support this out of the box.

The gil uses libjpeg for writing its JPEGs and adding a comment in libjped is as easy as calling jpeg_write_marker(). The problem was that the gil buries libjpeg calls under a few classes so I had to copy and paste some of this in order to redefine a new writer which supports comments.

Anyway I have included the extra code inline below, it adds a new helper function called jpeg_write_view_comment()

Use this new function like this:

 int quality = 70;
 jpeg_write_view_comment("image1.jpg", view, quality, "a comment damn it!!!");

Here is the extra code which I placed in a file called jpeg_writer_comment.h

#pragma once
#include "boost/gil/extension/io/dynamic_io.hpp"
using namespace boost;
using namespace boost::gil;
using namespace boost::gil::detail;
class jpeg_writer_comment : public file_mgr {
    jpeg_compress_struct _cinfo;
    jpeg_error_mgr _jerr;
    void init() {
        _cinfo.err=jpeg_std_error(&_jerr);
        jpeg_create_compress(&_cinfo);
        jpeg_stdio_dest(&_cinfo,_fp.get());
    }
public:
    jpeg_writer_comment(FILE* file)           : file_mgr(file)           { init(); }
    jpeg_writer_comment(const char* filename) : file_mgr(filename, "wb") { init(); }
    ~jpeg_writer_comment() { jpeg_destroy_compress(&_cinfo); }
    template 
    void apply(const View& view,int quality=100, const char* comment = NULL) {
        _cinfo.image_width  = (JDIMENSION)view.width();
        _cinfo.image_height = (JDIMENSION)view.height();
        _cinfo.input_components=num_channels::value;
        _cinfo.in_color_space = jpeg_write_support_private::type,
                                                           typename color_space_type::type>::color_type;
        jpeg_set_defaults(&_cinfo);
        jpeg_set_quality(&_cinfo, quality, TRUE);
        jpeg_start_compress(&_cinfo, TRUE);
        if (comment) {
        	jpeg_write_marker(&_cinfo, JPEG_COM, (const JOCTET*)comment, strlen(comment));
        }
        std::vector::type> > > row(view.width());
        JSAMPLE* row_address=(JSAMPLE*)&row.front();
        for (int y=0;y
    void write_view(const any_image_view& runtime_view) {
        dynamic_io_fnobj op(this);
        apply_operation(runtime_view,op);
    }
};

template 
inline void jpeg_write_view_comment(const char* filename,const View& view,int quality=100, const char* comment = NULL) {
    BOOST_STATIC_ASSERT(jpeg_write_support::is_supported);
    jpeg_writer_comment m(filename);
    m.apply(view, quality, comment);
}

Boost link error – undefined reference to boost filesystem detail copy_file( )

I had some difficulty today getting my code to link to boost::filesystem::copy_file() (linking to boost version 1.53.0, gcc v4.7.2), I suffered from link errors like this:

undefined reference to `boost::filesystem::detail::copy_file(boost::filesystem::path const&, boost::filesystem::path const&, boost::filesystem::copy_option, boost::system::error_code*)’

From reading this post, it seemed that my problem may have stemmed from my use of c++0x.

 

None of the suggested solutions in this thread worked for me & I double checked that had built boost with -std=c++0x.

 

In the end after looking through the code in filesystem/operations.hpp the only thing that fixed my linking problem was to #define BOOST_NO_CXX11_SCOPED_ENUMS before including , like this:

#define BOOST_NO_CXX11_SCOPED_ENUMS
#include 

This may well not be the best/proper way to fix the problem but it was the only thing that worked for me..

 

Other relevant links that I found are here, here and here.

 

boost filesystem compile warnings – boost system posix_category defined but not used

If you are using boost::filesystem in your C++ code and getting are some build warnings along the lines of:

 

‘boost::system::posix_category’ defined but not used

 

Then you may find that inserting the following code before #including boost/filesystem gets rid of them for you:

#ifndef BOOST_SYSTEM_NO_DEPRECATED
#define BOOST_SYSTEM_NO_DEPRECATED 1
#endif
#include 

This gets rid of some the deprecated stuff that was causing the warnings.

 

I found this handy tip here:

 

http://stackoverflow.com/questions/1814548/boostsystem-category-defined-but-not-used

 

Eclipse CDT – Using boost thread library with eclipse

If you are scratching your head about how to setup Eclipse and CDT to use the boost thread library then have a look at the first post in this thread:

 

http://www.eclipse.org/forums/index.php/m/787571/

 

It explains which project settings need to be changed.

 

Thanks to Robert!

 

Raspberry Pi – Install boost 1.50 C++ Libraries on Wheezy

If you are doing modern C++ development these days you will be using the boost libraries. I have started using the Raspberry Pi as a stand-in ARM platform for some smart-cam development while I wait for the actual hardware to become available and as such need to install boost. To this end, the boost 1.50 libs can be installed on wheezy as follows:
[crayon lang=”Shell”]
sudo apt-get install libboost1.50-all
[/crayon]
Now for a little example of using and building with the libs, consider this little test program that uses the boost regex library:

[crayon lang=”cpp”]

#include
#include
#include

int main() {

std::string text(“a fat cat sat on the mat”);
boost::regex re(“\\w+”);

boost::sregex_token_iterator i(text.begin(), text.end(), re, 0);
boost::sregex_token_iterator end;

for( ; i != end ; ++i ) {
std::cout << *i << ' '; } std::cout << std::endl; return 0; } [/crayon] If we stick this code into a file called it.cpp then we can build it using C++0x (C++11 ish), the standard c++ lib and the boost regex lib like this:

 

[crayon lang=”Shell”]
g++ -std=c++0x -lstdc++ -lboost_regex it.cpp
[/crayon]
This will output to a.out, which can then be executed like this:

./a.out
 

boost C++ read from serial port with timeout example

If you are doing any serial port communications these days in C++ and would like your code to be portable, then you are probably using boost’s asio::serial_port class.

One complication with using serial_port (and boost::asio more generally) is that it doesn’t provide a direct facility to allow synchronous blocking reads to time-out and return if no data arrives within a specified time period. Here is a little example that tries to read a character from COM3 (on windows..)

 

#include <boost/asio/serial_port.hpp>
#include <boost/asio.hpp>
using namespace boost;
char read_char() {
  asio::io_service io;
  asio::serial_port port(io);
  port.open("COM3");
  port.set_option(asio::serial_port_base::baud_rate(115200));
  char c;
  // Read 1 character into c, this will block
  // forever if no character arrives.
  asio::read(port, asio::buffer(&c,1));
  port.close();
  return c;
}

In this example read() will block forever if no data arrives to the serial port, this is not always what you want, especially when dealing with possibly noisy or unreliable rs232 communication.

In order to take advantage of read time-outs you have to issue asynchronous reads and incorporate a deadline_timer which will cancel the read after a specified time, i.e. if the read hasn’t received the data it was expecting before the deadline_timer expires, then it will be cancelled.

Using asynchronous IO in boost is a bit involved and it can be quite quite messy, so I have written small class called blocking_reader which will block while trying to read a single character, and will time out if a character hasn’t been received in a specified number of milliseconds. It can be used like this:

#include <boost/asio/serial_port.hpp>
#include <boost/asio.hpp>
#include "blocking_reader.h"
using namespace boost;
std::string read_response() {
    asio::io_service io;
    asio::serial_port port(io);
    port.open("COM3");
    port.set_option(asio::serial_port_base::baud_rate(115200));
    // A blocking reader for this port that
    // will time out a read after 500 milliseconds.
    blocking_reader reader(port, 500);
    char c;
    std::string rsp;
    // read from the serial port until we get a
    // \n or until a read times-out (500ms)
    while (reader.read_char(c) && c != '\n') {
        rsp += c;
    }
    if (c != '\n') {
        // it must have timed out.
        throw std::exception("Read timed out!");
    }
    return rsp;
}

The above code isn’t the most sensible or efficient but it shows the use of blocking_reader, which in this case times out reads after 500ms.

You open the serial_port as normal and then pass it to blocking_reader’s constructor along with a timeout value. You then use blocking_reader.read_char() to read a single character. If the read times out then read_char() will return false (otherwise it will return true!)

The code for blocking_reader can be downloaded from this GitHub repo

//   Copyright 2012 Kevin Godden
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//
// blocking_reader.h - a class that provides basic support for
// blocking & time-outable single character reads from
// boost::asio::serial_port.
//
// use like this:
//
// 	blocking_reader reader(port, 500);
//
//	char c;
//
//	if (!reader.read_char(c))
//		return false;
//
// Kevin Godden, www.ridgesolutions.ie
//
#pragma once
#include <boost/asio/serial_port.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
class blocking_reader
{
    boost::asio::serial_port& port;
    size_t timeout;
    char c;
    boost::asio::deadline_timer timer;
    bool read_error;
    // Called when an async read completes or has been cancelled
    void read_complete(const boost::system::error_code& error,
                        size_t bytes_transferred) {
        read_error = error;
        // Read has finished, so cancel the
        // timer.
        timer.cancel();
    }
    // Called when the timer's deadline expires.
    void time_out(const boost::system::error_code& error) {
        // Was the timeout was cancelled?
        if (error) {
            // yes
            return;
        }
        // no, we have timed out, so kill
        // the read operation
        // The read callback will be called
        // with an error
        port.cancel();
    }
public:
    // Constructs a blocking reader, pass in an open serial_port and
    // a timeout in milliseconds.
    blocking_reader(boost::asio::serial_port& port, size_t timeout) :
                                                port(port), timeout(timeout),
                                                timer(port.get_io_service()),
                                                read_error(true) {
    }
    // Reads a character or times out
    // returns false if the read times out
    bool read_char(char& val) {
        val = c = '\0';
        // After a timeout & cancel it seems we need
        // to do a reset for subsequent reads to work.
        port.get_io_service().reset();
        // Asynchronously read 1 character.
        boost::asio::async_read(port, boost::asio::buffer(&c, 1),
                boost::bind(&blocking_reader::read_complete,
                        this,
                        boost::asio::placeholders::error,
                        boost::asio::placeholders::bytes_transferred));
        // Setup a deadline time to implement our timeout.
        timer.expires_from_now(boost::posix_time::milliseconds(timeout));
        timer.async_wait(boost::bind(&blocking_reader::time_out,
                                this, boost::asio::placeholders::error));
        // This will block until a character is read
        // or until the it is cancelled.
        port.get_io_service().run();
        if (!read_error)
            val = c;
        return !read_error;
    }
};