SHARE
Facebook X Pinterest WhatsApp

Visual C++ Orcas Marshaling Library

One of the frequent criticisms of C++ is that it offers too many options to perform the same task. Consider the number of different options that exist for writing a text file that ship out-of-the-box with Visual C++—the C Runtime Libraries, the Standard C++ libraries, the Windows SDK I/O APIs, the .NET file APIs, MFC, […]

Written By
thumbnail
CodeGuru Staff
CodeGuru Staff
Aug 2, 2007
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

One of the frequent criticisms of C++ is that it offers too many options to perform the same task. Consider the number of different options that exist for writing a text file that ship out-of-the-box with Visual C++—the C Runtime Libraries, the Standard C++ libraries, the Windows SDK I/O APIs, the .NET file APIs, MFC, and even the FileSystemObjects available through COM. All of these libraries can write an identical text file, yet each has their own subtle advantages and pitfalls.

In the same way, the C++ developer has a wide array of options for converting between types in the .NET and COM world. Although most developers may resort to hand-coded conversion that involves boiling the data of a type down to blittable primitives (blittable data types are those that have the same in-memory format in the managed and native world, such as four-byte signed integers or Unicode characters), there is also the option of using the .NET type Marshal, which has various static methods for converting from one data type to another. Another option available to a C++ code compiled with /clr:pure or /clr:safe is the use of properties on the DllImport attribute to specify how a managed type is converted to a native type. With Visual C++ Orcas, there is a new technique for conversion: the C++ Marshaling Library.

The Marshaling Library provides a template-based approach to converting between native and managed data types. For simple conversions that have no memory management complexities, the syntax for converting from one data type to another is very simple:

#include <msclrmarshal.h>

TCHAR* c_style_string = _T("My C style string");
System::String^ dotNetString =
   msclr::interop::marshal_as<System::String^>(c_style_string);

When the returned object requires explicit memory clean-up, context-based marshaling needs to be used. With context-based marshaling, a managed marshal_context object needs to be created and passed to the marshaling method, and the results of the marshaling call are only valid for the lifetime of the marshal_context object. To convert the managed .NET string back to a C-style string, the following code would be required.

//declare new marshal_context
marshal_context^ mc = gcnew marshal_context();

//convert string from .NET to C-style
const TCHAR* new_c_style_string =
   mc->marshal_as<const TCHAR*>(dotNetString);

//get the length of the convert string
int strLen = (int)_tcslen(new_c_style_string) + 1;

//allocate a new character array to hold the string
TCHAR* copy_of_new_c_style_string = new TCHAR(strLen);

//copy to the new array
_tcscpy_s(copy_of_new_c_style_string, strLen, new_c_style_string);

//delete the marshaling context
delete mc;

When the marshal_context is deleted, any memory that has been allocated during marshaling calls is deleted, and this means a copy of the marshaled data needs to be made if the converted object will be accessed once the marshal_context object has been deleted.

A wide range of conversions is currently supported in the Beta 1 release of Visual C++ Orcas. The main header file (marshal.h) defines the base marshal type and string conversions between System::String and C-style strings (char* and wchar_t*). Marshal_atl.h provides conversion from COM strings (CComBSTR) and MFC strings(CStringA and CStringW) to managed strings, and marshal_cppstd.h goes between the standard C++ strings (std::wstring and std::string) to .NET. The final marshaling header file (marshal_windows.h) provides conversion between the managed IntPtr type and the native HANDLE type, and also supports the conversion to and from System::String for another two COM string types (_bstr_t and BSTR).

Recommended for you...

Video Game Careers Overview
CodeGuru Staff
Sep 18, 2022
Dealing with non-CLS Exceptions in .NET
Hannes DuPreez
Aug 5, 2022
Online Courses to Learn Video Game Development
Ronnie Payne
Jul 8, 2022
Best Online Courses to Learn C++
CodeGuru Staff
Jun 25, 2022
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2025 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.