Hi, I am Weidong Huang, an SDET on the VC++ library team. I joined MS six months ago and have had a wonderful experience so far. In this post, I would like to talk about a new feature of Orcas, the Marshaling Library, which is also the first feature I’ve worked on at MS.
What is marshaling library?
The marshaling library helps to marshal data types from managed to native and vice-versa in a simple and straightforward manner.
Customers programming in mixed mode are often faced with the need to marshal data types. Current solutions, like the runtime marshaling mechanisms, are complex and confusing. Thus, the marshaling library aims to provide an easier approach.
Currently, the marshaling library comes with two template functions – one requires a marshal_context and the other does not. I will explain the marshal_context a little later. Both functions have a similar structure: “To_Type marshal_as<To_Type>(From%)”. You use the marshaling library in the following ways and both functions return the result that you want.
(1) marshal_as<To_Type>(From %);
(2) marshal_context ctx; ctx.marshal<To_Type>(From %);
To me, it is really impressive and easy to remember because it looks like just the conversions we often use, such as “dynamic_cast<To_Type>(From)” and “static_cast<To_Type>(From)”.
Currently, we support 22 commonly used conversions. Most of these are conversions between managed type string to native string. Please refer to the marshaling library specification for the details.
What is marshal_context?
It would be better if we only needed to remember the function that does not require marshal_context. So why we need marshal_context and what kinds of conversions need marshal_context?
Basically, a marshal_context is a list of data nodes which contain the converted result data. Marshal_context takes care of the whole life of these data, from creating to destroying. You would have to remember to free the result manually if it weren’t for the marshal_context, for example when you convert a System::String^ to const char*, which is painful to most programmers.
Not all conversions need marshal_context. The marshal_context only comes out when you marshal from managed to native data types and the native type you are converting to does not have a destructor for automatic clean up. The marshaling context will help you destroy the allocated native data type in its destructor.
In case you don’t want to remember which conversion requires context and which doesn’t (or you like typing), you can always use the second one for all the conversions and the library will automatically direct it to the first one whenever necessary.
Tips of using marshaling library
· Feel free to use marshaling library instead of runtime marshal class. It is easier, safer and there are no performance drops.
· Feel free to extend the library. The library is designed be extensible by customers with conversions not supported by the library.
· Don’t use the conversion result after the context is out of range. Since all the results are managed by marshal_context, they are only valid until the context is deleted. To save any marshaled values, you must copy the values to your own variables.
· Use multiple marshal_contexts for large amount conversions when the memory of the context grows to cause frequent page swaps in your machine.
· Reference the marshaling library specification online for the detailed usage.
Any suggestions you might have about marshaling library will be a great help to us and highly appreciated. Feel free to ask questions about the usage and anything about the marshaling library!
ThanksWeidong HuangVisual C++ Library QA Team
I've not had to do mixed mode yet, so forgive me if any of the questions are obvious:
- Are there int/float/double conversions?
- const char to byte? Ranges of primitives in general?
- map to Dictionary<>?
- vector conversions to List<>?
The marshaling library provides only conversion between managed type and native type. Such as: System::String^ <-> const char*, System::String^ <-> std::string, System::String^ <-> std::wstring, etc.
All the types you mentioned above are native types so the conversion between them is not in the scope of marshaling library.
VC++ Library QA Team
Can someone develop extension templates to convert managed C# Struct to C Struct without runtime marshalling library (such as StructureToPtr and PtrToStructure)?
Ehm.. vector to System.Collections.Generic.List? map to Dictionary? How is that not managed <-> native?
Vector is no more or less native than std::string.
And int/double/float to System.Int32 & co.. It doesn't get any more native than that?
Sorry, I misunderstood your question. Currently we do not provide the conversion for int/double/float and Map, Vector. But you can extend the library yourself.
For the full list of conversion we provide now, please refer to the "http://download.microsoft.com/download/5/9/c/59cd0dc5-4691-4c3e-840c-66d865f27692/marshaling-library.xps"
Yes, you can extend the marshaling library to convert managed C# struct to C Struct. We will have detail MSDN document for how to extend the library.
My Orcas VC++ Express Beta 1 does not have any marshal*.h header...
Perhaps it will be in a future beta release?
is it possible for VC++ 2005 to take advantage of this library, say, by copying a few files only?
Marshaling library is not included in VC++ Express.
Theoretically, you can use marshaling library in VC++ 2005 by copying the header files to vc include\msclr. But we do not provide the support on this feature in VC++ 2005.
Hello, my name is Li Shao. I am a Software Design Engineer in Test in Visual C++ team. From June 3 to