Moving data between managed and unmanaged code or accessing data across the managed/unmanaged boundary that is transparent and incurs minimal overhead occurs only in the simplest of cases in most .NET-enabled languages. Some issues relating to marshaling data types between managed and unmanaged code include:
- The .NET common language runtime garbage collector does not support deterministic cleanup. This is not the standard experience in unmanaged code.
- The default layout of managed and unmanaged data structures is different.
- Unmanaged data types can be awkward to use in a managed environment or may have richer equivalents in managed code.
- Even if high fidelity translation between a managed and unmanaged type is possible, it often takes a very deep understanding of how the common language runtime marshals data to do this correctly and with acceptable performance.
For C++ developers, however, Managed Extensions for C++ can mix managed and unmanaged code and call traditional DLLs and COM objects directly. This makes Managed Extensions ideal for implementing the custom marshaling layer to link managed and unmanaged code. Implementing a managed application or class library with Managed Extensions for C++ is the easiest approach.
If you are interoperating with unmanaged code and managed code written in other languages, however, you need to use one of the following techniques:
- Custom marshaling
- Managed wrappers around unmanaged types
Note If you are responsible for an unmanaged library that managed code developers may use, you should provide an appropriate PInvoke signature, a reimplementation of the managed versions of the unmanaged functions and data, or wrapper classes and custom marshalers for your unmanaged data types. This will make it easier for a managed code developer to call your library from their code.