Interoperating Between Native Code and Managed Code

This document describes how to interoperate between managed code and native code.

Code that runs under the control of the common language runtime (CLR) is known as managed code. Code that does not run under the CLR is known as native code. The Windows API is one example of native code. Some features are available only to the managed programming model or to the native programming model. For example, many of the shell extensions are found only in the Windows API, which follows the native programming model. Frameworks such as Windows Presentation Foundation (WPF) are available only to managed code. There may be situations in which you want to combine both programming models in your applications.

Platform Invoke (P/Invoke) and Component Object Model (COM) interoperation enable managed code to use native functionality. For general information about these interoperability models, see Interoperability and Native and .NET Interoperability. For additional resources to help you interoperate between specific technologies, see Migrating Native Code to the .NET Framework.

The C++/CLI programming language lets you access managed components from native code. When you compile a Visual C++ application by using the /clr switch, the compiler creates metadata for the application that can be consumed by other managed applications, and enables the application to consume types and data in the metadata of other managed components. For more information about how to use C++/CLI in your applications, see C++/CLI Migration Primer.

Although interoperability enables managed code and native code to work together, the following issues can affect the performance, execution, and security of applications:

  • Marshaling. Data type representations in the .NET Framework differ from those in native code. Converting between the managed and native representations is known as marshaling. Marshaling occurs when a caller and a callee cannot operate on the same instance of data. For example, native code cannot act on managed strings or managed arrays, and vice-versa. The interop marshaler enables both the caller and the callee to appear to be operating on the same data although each has just a copy of the data. Therefore, repeated marshaling can negatively affect the performance of your application. For more information about marshaling data between managed code and native code, see Interop Marshaling.

  • Thunking. Regardless of the interoperability technique used, special transition sequences, which are known as thunks, are required each time a managed function calls an native function, and vice-versa. Because thunking contributes to the overall time that it takes to interoperate between managed code and native code, the accumulation of these transitions can negatively affect performance.

  • Code access security. Applications that use native code are subject to the code access security limitations of native code. However, you can disable these limitations through the compiler if it is safe to do so.

  • Threading models. COM marshals data between COM apartments or COM processes. When it calls between managed code and native code in the same COM apartment, the interop marshaler is the only marshaler involved. Calls between managed code and native code in different COM apartments or different processes involve both the interop marshaler and the COM marshaler.

The following resources can help you use .NET Framework features and functionality to enhance your existing applications.

.NET Framework Interoperability with the Windows API

.NET Framework Interoperability with ActiveX

.NET Framework Interoperability with COM and COM+

.NET Framework Interoperability with Visual Basic 6.0

Interoperability Between Windows Presentation Foundation and Other Technologies