Wednesday, 13 August 2014

Starting a C++ thread using a member function

Today I thought I'd share something that I have found useful on many occasions, that is launching a member function on a background thread in C++. Sometimes you can get away with simply firing up a normal thread and passing the current object pointer through as a parameter, however often this just isn't enough.

Launching a member function on a background can be done as follows. In this example we have a class called ExampleClass with a member function mymethod().
#include <thread>

ExampleClass *ec = new ExampleClass;

std::thread thread(&ExampleClass::myMethod, ec);
thread.detach();
And finally a complete sample to demonstrate the concept:
// required to use the std::thread class
#include <thread>

// not required for threading but used in
// this example to get console input
#include <iostream>
#include <string>

class ExampleClass
{
public:
 void myMethod();
};

void ExampleClass::myMethod()
{
 printf("thread running!");
}

int main(int argc, _TCHAR* argv[])
{
 ExampleClass *ec = new ExampleClass;
 std::thread thread(&ExampleClass::myMethod, &ec);
 thread.detach();

 std::string line;
 std::getline(std::cin, line);
}

A few words of caution

Be sure that the object outlives the thread function i.e. by allocating it on the heap. Otherwise if you thread function tries to access member variables it will access invalid memory and potentially cause access violations!

In the example above I new it up and do not bother to dispose it as my application exits anyway. In more complex programs you will need to consider where to free this memory safely.


Tuesday, 12 August 2014

Set a single file to not use precompiled header

If you are working on a C++ project, occasionally you will come across one or more files that cannot include the precompiled header (often named stdafx.h). However when removing the include for this file you will get an error similar to the following:

"unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?"

Don't worry we don't have to resort to removing the precompiled header entirely. Doing so would often largely increase the compile time and in fact break compilation under certain conditions. Instead the preferred method is to opt an individual file out of the precompiled header.

We can do this by right clicking on the .cpp file under the Solution Explorer and selecting Properties. Next select C++ and then Precompiled Headers in the side menu.

Before we make any changes set the configuration combo select to All Configurations, otherwise any changes we make will only apply to you current configuration i.e. Debug or release and as soon as you switch between them, compilation will fail again.

You should see one of the options listed is Precompiled Header which should be set to Use (/Yu). We need to set it to the Not Using Precompiled Headers option to tell Visual Studio that this .cpp file will no longer be making use of the precompiled header when it is compiled.

Note that the only file that should be set to Create (/Yc) is the precompiled header .cpp file (usually stdafx.cpp). This is the file that visual studio will compile first in order to generate the precompiled header.



After making these changes the above error should be resolved and your code will hopefully compile.

Debugging native code from .NET

Occasionally I've been caught out where Visual Studio won't seem to let me step into a native method that I've Pinvoked from a managed language. I thought it might make a decent blog topic as the answer isn't exactly what it seems. Often your first reaction is to assume that either Visual Studio doesn't support this, or if you know its possible you may be left pondering why it is currently not working.

Fortunately it is often simply that by default when debugging a C# project, Visual Studio only attached a managed debugger meaning it cannot debug native code. To enable mixed debugging, you simply have to enable native code debugging.

To achieve this right click on your C# project in the Solution Explorer and select Debug from the side menu. Right at the bottom you should see a sub-heading entitled Enable Debuggers.

Simply tick Enable native code debugging, re-run the debugger and hopefully stepping into native methods should work fine again. Also any valid breakpoints in native code should fire too.



Setting tab options with Visual Studio 2013

Most shared code projects demand that you follow their convention when it comes to Tab spacing, i.e. whether to use tabs or space characters and how much indentation to use. With Visual Studio you can change this setting on a per language basis. This means that if you work on different projects across programming languages that require different settings you won't get caught out.

To alter this setting go to Tools -> Options and select Text Editor from the side bar. You can then select All Languages to set a global tab setting across languages or select a specific language to change. Once an option is selected, the Tabs option will display the settings available.

Here I am demonstrating my Tab setting for C#:


As you can see the main options I am interested in are Tab and Indent size which set how many white space characters a tab represents. Also you have the option of using Tab characters or inserting white space characters into the document when the Tab key is pressed. The number inserted will be resolved using the Tab and Indent size options.

As long as you remember to set this up correctly you should never find yourself falling foul of your projects tabbing conventions.



Sunday, 10 August 2014

HTTP get request with C++ Boost::Asio

So the other day I found myself needing to make several networking calls in a C++ application I was developing in my spare time.

As you can expect there is not much networking wise built into C++ out of the box. As I was developing On Windows I could have gone down the tedious winsock route and practically reinvented the wheel however I decided my time was better spend using a pre-built framework to achieve what I wanted.

I settled on using the Asio library which is a part of the Boost framework, essentially an addon to the standard library which can be downloaded at http://www.boost.org. From my experience, while Boost is generally well documented, it is designed to be a relatively low level framework and as such I ended up implementing a basic HTTP Get helper class. 

What follows is how I achieved a basic HTTP get request using C++/Boost.

The fundamental thing to remember with TCP is that while data is guaranteed to arrive correctly due to CRC checks and re-transmission, we do not know when the data will arrive. Thus it is important to perform our request asynchronously in order to not block the rest of our program from executing while the data is transmitted. Therefore I will demonstrate how to achieve this asynchronous behaviour using boost.

First off lets look at what is involved with getting a socket connected to an ip address.

First we need to include the relevant header files and namespaces.
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
Before we can connect a socket we need to setup a Boost IO Service within our application. This runs an event loop which processes messages posted to and from various Boost components. Many of the examples you will find on the web run this on the Main Thread for the sake of brevity, as will mine. However for more complex programs you may wish to develop I would strongly advise moving this to a background thread so as to not block on your applications main thread.

Running a basic io_service is done as follows:
boost::asio::io_service io_service;

// queue some work to be done here

// io service will exit when queued jobs are completed
io_service.run();

Now that we have the basic setup we can begin the steps required to obtain the data from the web server. These go as follows:
  1. Connect to a socket on the web server
  2.  Send a HTTP Request header
  3.  Read the header response (up to you what to do here, in this simple example I throw it away)
  4. Read the HTML content
For performance reasons we use the async methods in the Asio library. These allow us to call a function such as connect and have the library call us back when that operation has completed. This is the preferred means of doing things predominantly for performance. Reading the response back in this async manner allows us to read and process chunks of data. This means we can start processing the start of the document while the rest is still on the wire being transferred and is a trick browsers use to improve performance.

So once we combine all those steps we end up with something like this:
// m_host should be in format such as "www.google.co.nz"
// m_url should be in format such as "/index.html"
void HTTPGetRequest::sendRequest()
{
 tcp::resolver::query query(m_host, "http");

 m_resolver.async_resolve(query, 
  [this](const boost::system::error_code& ec, tcp::resolver::iterator endpoint_iterator)
  {
   boost::asio::async_connect(m_socket, endpoint_iterator,
    [this](boost::system::error_code ec, tcp::resolver::iterator)
   {
    if (!ec)
    {
     std::ostream request_stream(&m_request);
     request_stream << "GET " << m_relativeURL << " HTTP/1.1\r\n";
     request_stream << "Host: " << m_host << "\r\n";
     request_stream << "Accept: */*\r\n";
     request_stream << "Connection: close\r\n\r\n";

     boost::asio::async_write(m_socket, m_request,
      [this](boost::system::error_code ec, std::size_t /*length*/)
     {
      boost::asio::async_read_until(m_socket, m_response, "\r\n\r\n",
       [this](boost::system::error_code ec, std::size_t length)
       {
        ReadData();
       });
     });
    }
   });
  });
}

void HTTPGetRequest::ReadData()
{
 boost::asio::async_read(m_socket, m_response, boost::asio::transfer_at_least(1),
  [this](boost::system::error_code ec, std::size_t /*length*/)
 {
  size_t size = m_response.size();
  if (size > 0)
  {
   std::unique_ptr buf(new char[size]);
   m_response.sgetn(buf.get(), size);

   m_receivedCB(buf.get(), size);
  }

  if (ec != boost::asio::error::eof)
  {
   ReadData();
   return;
  }

  m_socket.close();

  m_completeCB();
 });
}
Hopefully it is clear that chaining the async callbacks together carries out the steps listed earlier. Now that we have the bare bones of our network call we can add some meat and form it into a basic class. Note that while this class should be functional it is by no means designed to be totally complete. There are still error cases to consider for example.

Hopefully the following will provide you with a working sample to base your project on.

HTTPGetRequest.h
#pragma once

#include <string>

#include <boost/asio.hpp>
using boost::asio::ip::tcp;

typedef void(*HTTPRequestDataReceived)(char*, size_t);
typedef void(*HTTPRequestComplete)();

class HTTPGetRequest
{
public:
 HTTPGetRequest(
  boost::asio::io_service& io_service, 
  std::string host, 
  std::string relativeURL, 
  HTTPRequestDataReceived receivedCB,
  HTTPRequestComplete completeCB);
 
 ~HTTPGetRequest();

public:
 void sendRequest();

private:
 HTTPRequestDataReceived m_receivedCB;
 HTTPRequestComplete m_completeCB;

 std::string m_host;
 std::string m_relativeURL;

 tcp::socket m_socket;
 boost::asio::io_service &m_io_service;
 tcp::resolver m_resolver;

 boost::asio::streambuf m_request;
 boost::asio::streambuf m_response;

 void ReadData();
};
HTTPGetRequest.cpp
#include "stdafx.h"

#include "HTTPGetRequest.h"

HTTPGetRequest::HTTPGetRequest(boost::asio::io_service& io_service, std::string host, std::string clipURL, HTTPRequestDataReceived receivedCB, HTTPRequestComplete completeCB) :
 m_host(host),
 m_relativeURL(clipURL),
 m_io_service(io_service),
 m_socket(io_service),
 m_resolver(m_io_service),
 m_receivedCB(receivedCB),
 m_completeCB(completeCB)
{

}

HTTPGetRequest::~HTTPGetRequest()
{

}

// host should be in format such as "www.google.co.nz"
// url should be in format such as "/index.html"
void HTTPGetRequest::sendRequest()
{
 tcp::resolver::query query(m_host, "http");

 m_resolver.async_resolve(query, 
  [this](const boost::system::error_code& ec, tcp::resolver::iterator endpoint_iterator)
  {
   boost::asio::async_connect(m_socket, endpoint_iterator,
    [this](boost::system::error_code ec, tcp::resolver::iterator)
   {
    if (!ec)
    {
     std::ostream request_stream(&m_request);
     request_stream << "GET " << m_relativeURL << " HTTP/1.1\r\n";
     request_stream << "Host: " << m_host << "\r\n";
     request_stream << "Accept: */*\r\n";
     request_stream << "Connection: close\r\n\r\n";

     boost::asio::async_write(m_socket, m_request,
      [this](boost::system::error_code ec, std::size_t /*length*/)
     {
      boost::asio::async_read_until(m_socket, m_response, "\r\n\r\n",
       [this](boost::system::error_code ec, std::size_t length)
       {
        ReadData();
       });
     });
    }
   });
  });
}

void HTTPGetRequest::ReadData()
{
 boost::asio::async_read(m_socket, m_response, boost::asio::transfer_at_least(1),
  [this](boost::system::error_code ec, std::size_t /*length*/)
 {
  size_t size = m_response.size();
  if (size > 0)
  {
   std::unique_ptr<char> buf(new char[size]);
   m_response.sgetn(buf.get(), size);

   m_receivedCB(buf.get(), size);
  }

  if (ec != boost::asio::error::eof)
  {
   ReadData();
   return;
  }

  m_socket.close();

  m_completeCB();
 });
}
And finally Main.cpp to show it all in use...
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <vector>

#include <boost/asio.hpp>
#include <boost/bind.hpp>

using boost::asio::ip::tcp;

#include "HTTPGetRequest.h"

std::vector<char> g_data;

void OnDataReceived(char* data, size_t dataLen)
{
 // store data in vector for sake of demo...

 unsigned int oldSize = g_data.size();
 g_data.resize(oldSize + dataLen);
 memcpy(&g_data[oldSize], data, dataLen);
}

void OnRequestCompleted()
{
 // print contents of data we received back...

 g_data.push_back('\0');
 printf(&g_data[0]);
}

int _tmain(int argc, _TCHAR* argv[])
{
 boost::asio::io_service io_service;

 HTTPGetRequest req(
  io_service,
  "www.google.co.nz",
  "/index.html",
  OnDataReceived,
  OnRequestCompleted);

 req.sendRequest();

 io_service.run();

 // so we dont exit too early...
 std::string line;
 std::getline(std::cin, line);

 return 0;
}
After compilation that simple example sends an asynchronous GET request to google New Zealand and prints the output to the console window once it arrives. As I mentioned earlier for more complex situations, you may need to move the io_service to a background thread to avoid the main thread blocking.

I hope you find the following useful, as I mentioned earlier please bear in mind it does not handle every situation but should provide you with a basic starting point.

Feel free to comment with any questions or feedback you may have! Thanks for reading.

Thursday, 7 August 2014

Hello World

I've been toying with the idea of setting up a blog for a while now, I guess its about time I bite the bullet and take the first step. It might take me a while to sort out the layout of the blog, I've got a little on my plate at the moment and I'm new to Blogger but hopefully within a few weeks I'll have the final look and feel sorted.

As a Software Engineer (and I'm sure many of you can relate), I often make use of the internet to find useful coding tips, libraries, and most importantly whenever I stumble across a Windows function that is mysteriously missing from the MSDN documentation.

Occasionally and where possible when I come across anything I feel might be useful to someone else I'll try to post it here to fill the knowledge gap.

Watch this space....