Software

boost::bind example

posted Dec 5, 2011, 1:55 PM by Andrew Jessop   [ updated Dec 5, 2011, 1:58 PM ]

I find that I always forget the more intricate usages of boost::bind(), and that the examples provided in the boost documentation are always that little bit too confusing when I need to quickly remember the syntax I want.

I've been playing with boost::bind again recently and this time I've written a small set of examples for myself.  They include:
1) using placeholders and binding to a member function
2) passing in a value when binding
3) C library style callbacks (since I always think I can bind them for some stupid reason)

To build the example:
1) Copy the code into main.cc
2) sudo apt-get install build-essential libboost-system-dev
3) LDLIBS=-lboost_system make main

#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>

class TestObject
{
public:
    void callback(int value, const char* msg);
private:
};

//-------------------------------------------------//
//                C Library Code
//-------------------------------------------------//
void registerAndRun(void (*callbackFunction)(int, const char*, void* data), void* data)
{
    callbackFunction(3, "from C code", data);
}
//-------------------------------------------------//

extern "C" void c_callback(int value, const char* msg, void *data)
{
    // cast back to our object type and call the (correct) callback.
    // In practice you might have various callbacks on the object
    // that you'd call based on the parameters of this function
    // I.E. switch(value) case 1: ->read(); case 2: ->write() etc.
    reinterpret_cast<TestObject*>(data)->callback(value, msg);
}

void TestObject::callback(int value, const char* msg)
{
    std::cout << "TestObject::callback() - value: "
        << value << ", msg: " << msg
        << std::endl;
}

int main(int argc, char* argv[])
{
    typedef boost::function<void(int, const char*)> Function;
    // Example 1: bind TestObject::callback()
    // passing in both values as placeholders for later
    TestObject testObject;
    Function function1(
        boost::bind(&TestObject::callback, testObject, _1, _2)
        );
    function1(1, "hello");

    // Example 2: bind TestObject::callback() passing in a value now
    typedef boost::function<void(int)> Function2;
    Function2 function2(
        boost::bind(&TestObject::callback, testObject, _1, "value now")
        );
    function2(2);

    // Example 3: using a static extern "C" proxy function for C function pointers
    registerAndRun(c_callback, &testObject);
   
}


Moving from Linux to Windows

posted May 7, 2011, 7:53 PM by Andrew Jessop   [ updated May 13, 2011, 4:09 PM ]

Recently I've been doing some C# and Java development on windows.  I've found the move from Linux development back to windows a little bit of a shock as I've begun to rely on several Linux features heavily.
Below is a list of useful and important tools I've found to make a useful Windows (XP) development environment, and to help the transistion go smoothly:

Ninite.com
General Info: http://ninite.com/
Automated downloader & installer for many common and useful Windows applications.
Instructions:
  • I select a set of applications similar to the following...
 Web Browsers  Messaging  Media  Runtimes  Imaging  Documents         Other  Utilities  Compression  Dev Tools
chrome   pidgin
iTunes  Flash  Paint.NET                       Acrobat Reader Dropbox ImgBurn 7-Zip Python
firefox    K-Lite Codecs Java GIMP PDFCreator  
  JDK
      .NET           Notepad++ 

Process Explorer
Instructions:
  • Unzip it and use the executable.  In the Options menu, choose:
    - Replace Task Manager
    - Hide When Minimised
    - Allow Only One Instance
Power Resizer
Allows you to resize windows in a similar manor to Windows 7. 
Instructions:
  • Customise source & rebuild so that moving a window to the top of the screen fully maximises it - same behavior to Windows 7.
GVim
Graphical vi editor for windows.
Instructions:
  • In the installer, select "create .bat files for command line usage"
  • Add C:\Program Files\Vim\vim73 to system PATH environment variable

MinGW/MSys
The basic GNU Unix tools/apps for windows (like ls, rm, grep, find, zip, tar, cat, file etc.)

Instructions:
  • Extract it to C:\MinSYS
  • Add C:\MinSYS\bin and C:\MinSYS\msys\1.0\bin to system PATH environment variable
  • In a terminal run mingw-get install msys-man msys-bash msys-bzip2 msys-core msys-coreutils msys-findutils msys-file msys-gawk msys-grep msys-gzip msys-less msys-sed msys-tar msys-unzip msys-wget msys-zip msys-mintty
  • Create a shortcut to C:\MinSYS\msys\1.0\msys.bat file and place in quick launch bar.
  • Edit the shortcut properties:
      - Start In: "C:\MinSYS\msys\1.0\bin"
      - Target: "C:\MinSYS\msys\1.0\msys.bat" --mintty
      - Run: Minimized
      - Layout Tab: (Width=1, Height=1)
      - Change icon to C:\MinSYS\msys\1.0\bin\mintty.exe's icon
  • Reopen a terminal via the new shortcut
  • Create /etc/fstab
      #Win32_Path Mount_Point
      c:/minsys /minsys
      c:/DOCUME~1/ADMINI~1/MYDOCU~1 /home/Administrator
  • Close terminal and reopen to get the new home area mount point
  • Edit C:\MinSYS\msys\1.0\etc\profile or create your own ~/.profile:
    export PS1='\[\e]2;\u@\h:\w\a\]\u@\h:\[\e[1;34m\]\w\[\e[0;39m\]$ '
    alias ls='ls -U --color=auto'  # -U sorts by letter, not capitalisation
    alias grep='grep --color=auto'
    alias egrep='egrep --color=auto'
    alias fgrep='fgrep --color=auto'
  • Change mintty's settings (Right Click->Options)
      - Looks -> Cursor -> Block
      - Text -> Font -> Size 10
    or write ~/.minttyrc with:
  • FontHeight=10
    CursorType=block
    Term=xterm
  • Add gvim's path to PATH environment variable in .profile if not added to Windows system PATH var.
  • setup /etc/inputrc so that CTRL+LeftArrow and CTRL+RightArrow work in the terminal:
    • # mappings for Ctrl-left-arrow and Ctrl-right-arrow for word moving
      "\e[1;5C": forward-word
      "\e[1;5D": backward-word
      "\e[5C": forward-word
      "\e[5D": backward-word
      "\e\e[C": forward-word
      "\e\e[D": backward-word
    Note: if you can't find the correct mapping in a terminal press CTRL+V then CTRL+LeftArrow - this will output the mapping.  Replace ^[ with \e.
  • To start any program, view a directory in explorer, or use the "associated program" for a file use start <arg> http://support.microsoft.com/kb/126410
Nmap
General Info: http://nmap.org/
Network scanner/exploration tool.
Instructions:
  • Install WinPCap
NX Windows Client
X Windows remote compression technology.
Instructions:
  • Use "custom settings", choose "run command: gnome-terminal"

iPhone Explorer

General Info: http://www.macroplant.com/iphoneexplorer/
Allows you to explore the file system on your iPhone, add or delete files and folders through a GUI.
Download: http://www.macroplant.com/release/iPhoneExplorerPC_2101.zip
Instructions:
  • Simply install and use. (requires iTunes to be installed)

C++ vtable

posted Mar 31, 2011, 12:05 AM by Andrew Jessop

I've been looking for a reference on vtables in C++ for a little while.  They are compiler implementation specific so it can be hard to find the info without reading the source code for g++ etc. Today I found a good intermediate level reference: http://www.avabodh.com/cxxin/cxx.html.  This guy also has a C from Asm http://www.avabodh.com/cin/cin.html reference that is worth a look.

Using boost::asio for non-blocking IO with 3rd party API

posted Feb 8, 2011, 10:18 PM by Andrew Jessop   [ updated Dec 23, 2011, 3:45 AM ]

Recently I have had to deal with a C++ library that maintains control of the creation, binding, connection, buffering etc of a TCP connection and associated file descriptor.  I wanted to use the boost::asio framework for this application and below is how I went about it.

Update: This doesn't seem to be using epoll() or select() as I had intended.  The code will need changing.

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

#include <custom/api.hh>

class
APIWrapper

{
public:
    ...
    void connect()
    {
        // other API stuff here
        mySocket.assign(boost::asio::ip::tcp::v4(), api->fd());
        boost::asio::ip::tcp::socket::non_blocking_io nb(true);
        mySocket.io_control(nb);
        
        startIO();

    }

    void startIO()
    {
        mySocket.async_read_some(boost::asio::null_buffers(),
            boost::bind(&APIWrapper::ioRead, this)
        );
        mySocket.async_write_some(boost::asio::null_buffers(),
            boost::bind(&APIWrapper::ioWrite, this)
        );
    }

    void action()
    {
        // Since the API either directly, or via a buffer, writes to the socket
        // nothing else has to be done here. We will get the ioWrite() callback
        // from boost::asio once we're ready to write data back out.
        api->action();
    }
    ...
private:
    boost::asio::ip::tcp::socket mySocket;
    API *api;

    void ioRead()
    {  
        api->read();
    }
    void ioWrite()
    {
        api->write();
    }
};

int main()
{
    // Create the main service
    boost::asio::io_service io_service;
    boost::asio::io_service::work work(io_service);

    // Connect via API
    APIWrapper client;
    client.connect();

    // Perform some initial action
    client.action();

    // Start the main event loop
    io_service.run();


    return 0;
}

gcc standard libraries

posted Feb 2, 2011, 3:45 AM by Andrew Jessop   [ updated Feb 8, 2011, 11:01 PM ]

While setting up a 'bare bones' program on a Philips ARM LCP21xx series Microcontroller, I encountered the need to link the standard library in a different place.  While flicking through the GCC Manual, I found the following useful debugging options:

-print-libgcc-file-name
Same as -print-file-name=libgcc.a.
This is useful when you use -nostdlib or -nodefaultlibs but you do want to link with libgcc.a. You can do
     gcc -nostdlib files... `gcc -print-libgcc-file-name`

1-5 of 5