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).
4 responses so far ↓
1 Stephane // Jul 17, 2007 at 8:16 pm
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 Vivek Ragunathan // Jul 19, 2007 at 12:02 am
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 Vivek Ragunathan // Jul 19, 2007 at 12:02 am
I guess that errors I attached previously have been cut off. Here they are:-
Error 1 error C2143: syntax error : missing ‘;’ before ‘
4 Vivek Ragunathan // Jul 19, 2007 at 12:04 am
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 Comment