Extending the marshal_as library

A couple of blog entries ago, I had written about the marshal_as library that is introduced in Orcas and how it’s very useful for mixed-mode string conversions. While the built-in functionality only allows string conversions, it’s also possible to extend marshal_as functionality to support other type conversions. As an example of doing this, I have written a sample extension that supports converting between the Windows Forms Rectangle structure and the Win32 RECT structure. For the sake of completion I have also added specializations for the MFC CRect wrapper (which is a thin wrapper around the RECT structure). Here’s my extension (put into a separate header file) :-

namespace msclr
{
    namespace interop
    {
        template<> System::Drawing::Rectangle
            marshal_as<System::Drawing::Rectangle, RECT> (
            const RECT& from)
        {
            return System::Drawing::Rectangle(from.left, from.top,
                from.right - from.left, from.bottom - from.top);
        }

        template<> System::Drawing::Rectangle marshal_as<
            System::Drawing::Rectangle, CRect> (
            const CRect& from)
        {
            return System::Drawing::Rectangle(from.left, from.top,
                from.Width(), from.Height());
        }

        template<> RECT marshal_as<RECT, System::Drawing::Rectangle>(
            const System::Drawing::Rectangle& from)
        {
            System::Drawing::Rectangle rectangle = from; //remove const
            RECT rect = {rectangle.Left, rectangle.Top,
                rectangle.Right, rectangle.Bottom};
            return rect;
        }

        template<> CRect marshal_as<CRect, System::Drawing::Rectangle>(
            const System::Drawing::Rectangle& from)
        {
            System::Drawing::Rectangle rectangle = from; //remove const
            return CRect (rectangle.Left, rectangle.Top,
                rectangle.Right, rectangle.Bottom);
        }
    }
}

Effectively I’ve added four specializations for the four conversions that I need. Note how I have put the conversions into the msclr::interop namespace. This is to allow me (and anyone else) to use these additional conversions the same way I’d be using marshal_as for the regular conversions.

Now using these conversions would be quite trivial as show below.

//To Rectangle

RECT rect = {10, 10, 110, 110};
System::Drawing::Rectangle rectangle =
    marshal_as<System::Drawing::Rectangle>(rect);

CRect mfcRect(20, 20, 220, 220);
rectangle = marshal_as<System::Drawing::Rectangle>(mfcRect);

//From Rectangle

RECT rectBack = marshal_as<RECT>(rectangle);

CRect mfcRectBack = marshal_as<CRect>(rectangle);

One important thing to be aware of is that in all four conversions I’ve added there is no need to handle context as there is no explicit need for memory deallocation. This may not always be the case as we’ll see in the next blog entry (hopefully soon).

Advertisements

4 thoughts on “Extending the marshal_as library

  1. HEllo Nish I work for a company that is lookign for someone with your talents especially c++
    win32 and unix to hire immediately up to 200k total company email me if interested

  2. Hello Nish

    I tried your code above. I am getting errors. I have attached the errors at the bottom for you to have a look.

    And I have a naive question about the template usage you have shown in the code. The template method definition is as follows:-

    template System::Drawing::Rectangle marshal_as(const CRect& from) { … }

    And what does the usage

    rectangle = marshal_as(mfcRect);

    tell us, while we have specified only one template argument ?
    I am not aware of this kind of usage.
    Error Message(s)
    —————-
    Error 1 error C2143: syntax error : missing ‘;’ before ‘

  3. C2143: syntax : missing ‘;’ before ‘less than symbol’11
    C2988: unrecognizable template declaration/definition11
    C2059: syntax : ‘less than symbol’11
    C2143: syntax : missing ‘;’ before ‘less than symbol’19
    C2086: ‘System::Drawing::Rectangle msclr::interop::marshal_as’ : redefinition19
    C2988: unrecognizable template declaration/definition19
    C2059: syntax : ‘less than symbol’19
    C2143: syntax : missing ‘;’ before ‘{’26
    C2447: ‘{‘ : missing function header (old-style formal list?)26
    C2146: syntax : missing ‘;’ before identifier ‘marshal_as’33
    C4430: missing type specifier – int assumed. Note: C++ does not support default-int33
    C2143: syntax : missing ‘;’ before ‘less than symbol’33
    C4430: missing type specifier – int assumed. Note: C++ does not support default-int33
    C2371: ‘msclr::interop::marshal_as’ : redefinition; different basic types33
    fatal C1903: unable to recover from previous error(s); stopping compilation33

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s