Sunday, 21 October 2012

Calling Managed C# code from Native C++

Introduction

Why Do This?

There is a lot of power and flexibility available in the .NET world that is not available in the standard C++ STL & ATL libraries. It would be very useful to be able to tap into these capabilities in an otherwise highly efficient and optimised native C++ program.

What do you mean by native / managed?

Native code is compiled into machine code that runs directly on the host computer. Once compiled, it is very lightweight and fast. Managed code, on the other hand, is compiled into bytecode that needs an interpreter to be able to run on the host computer. This interpreter is provided by the .NET framework and therefore to run managed code you need to have the .NET framework installed. The benefit of this is that there are various programming languages, such as C# and VB.NET, that compile to the same bytecode, so you can pick your favourite. Also, managed code needs to be compiled for the operating system it is running on. A managed program can run on any operating system that has .NET framework installed.

Why is this difficult?

You cannot call a C# function directly from a native C++ program. You have to have a marshalling function in the middle, written in managed C++. This is because .NET hides the complexity of pointers by making all objects reference-types by definition. It then manages the life-cycle of these objects and references through managed pointers. You have to convert objects from managed .NET classes into native classes.

How is it done?

In Visual Studio, you need to have different projects in the same solution if you want to mix languages. For example, if you want to write code in C++ and C#, you need to have a C++ project and a C# project. You can mix managed C++ and native C++ in the same project, but there are some tricks you need to do to get it to work. That is what the main point of this blog is about, how to set up the C++ project to work with mixed native and managed code.

Setting up the project

Solution configuration

The solution has 2 projects, one is a C# project and the other is C++.

Solution Configuration

C# Project

The C# project is set up as a class library, meaning that it does not have an entry point and cannot be run as a program. Instead, the output is a DLL that can be linked to the other project in the solution. I have written a static function that does some formatting using the System.DateTime class, which is not available in native C++.

CLRClass.cs

using System;

namespace CSharpProject
{
    public static class CLRClass
    {
        public static string FormatDateTimeClr(int year, int month, int day, string format)
        {
            DateTime dt = new DateTime(year, month, day);
            return dt.ToString(format);
        }
    }
}

C++ Project

The C++ project is set up as a native console application. This has a main method that does the work of the program and therefore that is the entry point to the application. If this is a fairly big application, it is a good idea to use pre-compiled headers. This means that the standard header, stdafx.h, is compiled once and linked once to all the code files in the program, rather than copying in the contents of this to all the code files. Compilation will be much faster and also the program will be leaner because only the necessary code will be included in the source. However, you cannot include a native pre-compiled header in a managed C++ file. The way round this is to have a native stdafx.h and a managed stdafx.h, and generate 2 precompiled headers.

The mechanism that tells the program to generate a precompiled header is by having a dummy code file called stdafx.cpp that includes stdafx.h and has the setting to generate the precompiled header. For example, the settings for stdafx.cpp in my project is shown here;

Precompiled Header settings for stdafx.cpp
In order to generate a managed pre-compiled header file, I create two new source files, CLRstdafx.h and CLRstdafx.cpp. The source for stdafx.h, CLRstdafx.h and CLRstdafx.cpp are shown here;

stdafx.h

#pragma once

#include <string>
#include <stdio.h>
#include <tchar.h>
#include <iostream>

CLRstdafx.h

#include "stdafx.h"
#include <vcclr.h>

CLRstdafx.cpp

#include "CLRStdAfx.h"

 The CLR'd stdafx.h includes vcclr.h because this is a managed header and therefore cannot go in the native header file. Then, the settings for CLRstdafx.cpp are as follows;

Precompiled Header settings for CLRstdafx.cpp
As you can see, the pre-compiled header is set to CLRStdAfx.h and the pre-compiled header output file is NativeApplicationCLR.pch. Therefore, any managed source file will have to have these same settings in order to use the CLR pre-compiled header.

The managed C++ file that converts the data to and from native and managed code is declared in CLRInteropHeader.h and defined in CLRInteropFile.cpp.

CLRInteropHeader.h

std::wstring FormatDateTime(
    int year,
    int month,
    int day,
    std::wstring& format);


CLRInteropFile.cpp

#include "CLRstdafx.h"
#include "CLRInteropHeader.h"

using namespace CSharpProject;

std::wstring FormatDateTime(int year, int month, int day, std::wstring& format)
{
    System::String^ clrString = gcnew System::String(format.c_str());
    System::String^ formattedString =
        CLRClass::FormatDateTimeClr(year, month, day, clrString);
    pin_ptr<const wchar_t> wch = PtrToStringChars(formattedString);
    return std::wstring(wch);
}

The format specifier for the date-time is provided as a reference to a string, which needs to be converted to a .NET version of a string before passing to the C# function. Then, the results have to be converted back into a native string before passing back to the calling native function. In order for this code to work, a reference from the C++ to the C# project is required.

Adding Reference to CSharpProject
Then the program is finally ready to use the .NET features.

Program.cpp

#include "stdafx.h"
#include "CLRInteropHeader.h"

int _tmain(int argc, _TCHAR* argv[])
{
    int year = 2014;
    int month = 07;
    int day = 12;
    std::wstring format(L"yyyy-MMM-dd");
    std::wstring formattedString =
        FormatDateTime(year, month, day, format);
    std::wcout << formattedString;
    return 0;
}

And the final output;

Result of Running Program

Thursday, 19 April 2012

Binding in Windows Presentation Foundation (WPF)

What is this post all about?

Any programmer, novice or professional, who has wanted to pick up WPF and thought "hey, I know a few programming languages already. How hard could learning a new one be?" has found themselves rapidly and painfully disillusioned.

There is nothing inherently difficult about the concept of WPF. There are essentially 2 components; XAML and your preferred .NET language out of C# or VB.NET. XAML is a glorified version of XML, but tuned towards application programming. It is used to control the aspects of the application related to display and behaviour, whereas the traditional programming language is for aspects related to data and business logic.

Why is XAML difficult?

WPF is firmly grounded in the concept of MVC (Model-View-Controller) or MVVM (Model-View-ViewModel), depending on which book you read. The idea is that the view does not 'own' any data. Your model owns data, and it is your controller's / view model's job to handle user interaction and to marshal data in and out in a way that suits the application's usage. "If the view cannot own any data," I hear you ask, "how does it display anything to the user?" Good question. Through data binding.

Tell me more about binding...

Ok, since you asked so nicely. Binding is the act of linking a property's value to another property. Depending on how it is set up, a change in one property causes an event to fire which causes the other property to automatically update. If you have a binding between the text in some text box and a string property in your model, when the user navigates away from the text box after typing something, a property changed event gets fired, causing an update of the value in the model.

How does binding work? Literally the only way to answer is by magic. There are so many ways to bind data that it really comes down to horses for courses. You could define a resource in your window that points to the data model and bind the property to that. You could set the DataContext of some control and bind to that. There are more ways than I care to go into now.

The most confusing thing is when you bind a control that displays a collection of items to a collection in a data model. The control somehow just knows that it has to display each item next to each other, or on top of each other, etc. depending on the type of control. For example, you could bind a dropdown box to a List<String> property and it will allow you to select one of the items from that collection. It gets even more confusing when you bind a property of some other control to a property in that collection control. When you select a different item, the bound property also changes.

You're confusing me :(

No doubt. I'm confusing myself if I'm perfectly honest. That is why I spent days writing an application so that I could illustrate what I am talking about with an example. It is a very rudimentary contacts list type application. You can scroll through a list of contacts, click on one, and it will show you more details about the contact in question. You can download the compiled application here;

http://dl.dropbox.com/u/21044234/ContactsLayout.exe

And if you are feeling brave, you can get the source code here;

http://dl.dropbox.com/u/21044234/ContactsLayout.zip

It is built in Visual Studio 2010 Express. You will notice from the source code that, apart from the model data setup, it contains absolutely no source code. The entire application, from the user interaction through to the data presentation, is written in XAML and bound to the data model. It illustrates many of the powerful ways that WPF can be used to write pretty and interactive applications, which is what I like about it.

Sunday, 18 March 2012

Synchronised and Padded Iterators

Synchronised and Padded Iterators

What are they and why use them?

An iterator is something that can be used to loop over a collection of related items. For example, you could have a list of objects in an array which you would like to perform some operation on. An iterator allows you to get the value and step to the next item of interest.

Padded Iterators

Usually, you would only be interested in getting the values of objects in the array. Trying to dereference an index which does not point to an item in an array would result in a runtime error, such as an array out of bonds exception. However, there are cases where you might want to return some sort of value anyway, despite a value not existing in the array. An example would be where two arrays represent events in time, such as a sampled time series. You want to output these two time series aligned in time, such that you get
Time stamp - Value1 - Value2
However, what if these time series might not match up exactly, such that time series 1 has values where time series 2 does not, or vice versa? This is where padded iterators come in. They allow you to give a value at any index, whether one exists or not. You can specify what value to return if one does not exist.

Synchronised Iterators

Synchronised iterators are useful in situations where you would like to iterate over several lists of objects at once. In the example above, you want to get the value out for both time series for a specified time stamp and display them alongside each other. Then, you want to increment the time stamp of all lists being iterated over at once.

Source Code

Padded iterator code

class PaddedIterator
{
    public PaddedIterator(
        List<double> Values, DateTime DataStart, String PadVal)
    {
        _Values = Values;
        _DataStartDate = DataStart;
        _PadVal = PadVal;
        _Iterator = _Values.GetEnumerator();
    }

    public override string ToString()
    {
        if (this.CurrentDate >= _DataStartDate && _MoreData)
        {
            //return dereferenced iterator
            return _Iterator.Current.ToString();
        }
        else
        {
            // return padded value
            return _PadVal;
        }
    }

    public void MoveNext()
    {
        this.CurrentDate += this.Increment;
        if (this.CurrentDate >= _DataStartDate && _MoreData)
        {
            _MoreData = _Iterator.MoveNext();
        }
    }

    public DateTime CurrentDate {get;set;}

    public TimeSpan Increment {get;set;}

    private List<double> _Values;
    private List<double>.Enumerator _Iterator;
    private DateTime _DataStartDate;
    private String _PadVal;
    private bool _MoreData = true;
}

Explanation

In the above C# code, you would first construct a list of double values you would like to iterate over. Then, you construct a padded iterator with a representative start date of the first value and what you would like to give out if you ask for a data value that does not exist. Before using the iterator, you would set the CurrentDate and Increment properties. The CurrentDate is when the iterator starts giving values for, which would either be before or at the beginning of the data. In it's current form, it would not work to give it a CurrentDate that is within the data, as it always starts incrementing from the start of the data. The increment tells the iterator what value to add to the current date each time it is incremented.

Synchronised iterator code

class SynchronisedIterator
{
    public SynchronisedIterator(
        DateTime ReferenceDate, TimeSpan Increment, String PadVal)
    {
        this.Iterators = new List<PaddedIterator>();
        _EndDate = _CurrentDate = _ReferenceDate = ReferenceDate;
        _Increment = Increment;
        _PadVal = PadVal;
    }

    public List<PaddedIterator> Iterators {get;set;}

    public void AddIterator(List<double> Values, DateTime StartDate)
    {
        PaddedIterator Iterator =
            new PaddedIterator(Values, StartDate, _PadVal);
        Iterator.CurrentDate = _ReferenceDate;
        Iterator.Increment = _Increment;
        this.Iterators.Add(Iterator);

        //Recalculate end date to include new data
        int DataSpan = Values.Count * (int)_Increment.TotalDays;
        int OffsetDays = (int) (StartDate - _ReferenceDate).TotalDays;
        DateTime DataEndDate = _ReferenceDate +
            TimeSpan.FromDays(OffsetDays + DataSpan);
        if (DataEndDate > _EndDate) _EndDate = DataEndDate;
    }

    public override String ToString()
    {
        String Row = _CurrentDate.ToShortDateString();
        foreach (PaddedIterator It in this.Iterators)
        {
            Row += string.Format("\t{0}", It);
        }
        return Row;
    }

    public void NextRow()
    {
        _CurrentDate += _Increment;
        foreach (PaddedIterator iterator in this.Iterators)
        {
            iterator.MoveNext();
        }
    }

    public bool MoreData()
    {
        return (_CurrentDate < _EndDate);
    }

    private DateTime _ReferenceDate;
    private DateTime _CurrentDate;
    private DateTime _EndDate;
    private TimeSpan _Increment;
    private String _PadVal;
}

Explanation

In this example, the synchronised iterator holds a reference to a collection of padded iterators. The padded iterators know about the data that is being iterated over, and when to give a data value and when to give a padding value. The job of the synchronised iterator is to output a row of records with the date and the representative value of that date from all the padded iterators.
The synchronised iterator is given a reference start date which is the date that you would like to start returning values for. Then, the synchronised iterator will set up it's list of padded iterators with the current date as the reference start date. The end date is re-calculated for each padded iterator that is added.

Program code

class Program
{
    static void Main(string[] args)
    {
        List<double> myList = new List<double> { 10, 20, 30, 40, 50 };
        SynchronisedIterator synchronisedIterator =
            new SynchronisedIterator(new DateTime(2000, 1, 1),
                TimeSpan.FromDays(2), "None");

        synchronisedIterator.AddIterator(myList, new DateTime(2000, 1, 1));
        synchronisedIterator.AddIterator(myList, new DateTime(2000, 1, 15));
        synchronisedIterator.AddIterator(myList, new DateTime(2000, 1, 6));
        synchronisedIterator.AddIterator(myList, new DateTime(2000, 1, 3));
        synchronisedIterator.AddIterator(myList, new DateTime(2000, 1, 8));

        while (synchronisedIterator.MoreData())
        {
            Console.WriteLine(synchronisedIterator);
            synchronisedIterator.NextRow();
        }

        Console.ReadKey();
    }
}

Explanation

Because much of the complexity of how to iterate through the data, how to format the data, and whether to give values or to pad is hidden within the iterators, the actual program that constructs and uses these iterators can be quite simple.
In this example, I am creating a single list of double values which will be iterated over by several padded iterators. The synchronised iterator is constructed by telling it that it will start giving values from 1 Jan 2000, and that each value is 2 days apart. Whenever there is no value at a particular date, it will pad with the word "None". The actual padded iterators are added by calling AddIterator with the data and what date the data starts from.
Iterating over all the data is done with the while loop and just keeps churning out data until there is no more.

Result

Output of Program

Saturday, 11 February 2012

Creating a numeric left/right control

Why create a numeric left/right control?

A numeric up/down control, also called a spinbox, is used where properties of a form can be set over a continuous range between two extremes. This could be things like month of the year, where the month can only be an integer between 1 and 12.

In Windows Forms, this control looks like a text box with two tiny little arrows to increase or decrease the number.

NumericUpDown






It has several useful features when it has the focus. This includes being able to increase or decrease the numbers by pressing the up and down keys on the keyboard, or using the scroll wheel on the mouse to rapidly change it.

The problem is when it is being used to represent information that is horizontally aligned. Let's say you have a row of objects, and you want to use the spinbox to select which object is selected. Using up and down keys will confuse people. In my case, I needed to page through screens of time series data. A time series is a very long series of data, where the x-axis is time, and is almost always horizontally aligned. This is why I need the buttons to be pointing left and right.

What would be great is if the NumericUpDown control had a property you can toggle, which would just put the buttons on the left and right of the text box! This would save a lot of hastle. Unfortunately, as the name suggests, this is not possible. So I decided to create my own re-usable control that I can place on forms.

Creating a numeric left/right control

Create a new Visual C# project in Visual Studio. Then create a new user control.

Create new user control

I called the control NumericLeftRight. A grey canvas appears for you to create your control. Drop a NumericUpDown and two Button controls onto the canvas and arrange them either side of the NumericUpDown. Unfortunately, there is no way to turn off the up and down buttons on the NumericUpDown, so you will have to cover the up and down buttons with the right button. Change the text in the buttons to angle brackets to represent left and right operation.

Laying out the controls

Double click on the buttons to create click handers for them. In the click handlers, call the NumericUpDown.UpButton() and NumericUpDown.DownButton() methods. Also, expose the NumericUpDown control through a property. This is so that you can set the NumericUpDown control's settings , such as maximum and minimum, in the initialisation code for the form you drop it onto.

Click handlers and exposed NumericUpDown property

Compile your project and you are ready to add it to your form. Go back to the form designer and open the toolbox. You should see the user control for the NumericLeftRight available to drop onto the form.

The control appears in the toolbox

Drag the NumericLeftRight onto the form. Everything should be ready to go! Compile and launch the program and test that the buttons do increment and decrement the number in the NumericUpDown. In the properties window, the NumericUpDown property that I exposed can be seen in the Misc category at the bottom. You can expand it to see all the internal properties. However, you cannot set these properties here and have them applied at runtime. The designer does not apply these changes permanently for some reason. You need to go into the Form1.Designer.cs code directly and add the values to the properties manually.

Manually set the properties in the designer generated code
Hopefully, this should be everything you need to do in order to create a usable NumericLeftRight control. Compile and run, then spin away!

Using the form