Sunday, October 07, 2007

Mixed Assembly

C++ supports interoperability features that allow managed and unmanaged code to coexist and interoperate within the same assembly or in the same file. C++ assembly which has both native and managed code is called as mixed assembly. They contain machine instructions as well as MSIL instruction. An existing application consisting entirely of unmanaged functions can be brought to the .NET platform by re-compiling just one module with the /clr compiler switch. This module is then able to use .NET features, but remains compatible with the remainder of the application. In this way, an application can be converted to the .NET platform in a gradual, piece-by-piece fashion. It is even possible to decide between managed and unmanaged compilation on a function-by-function basis within the same file. Assemblies compiled with /clr can call managed and unmanaged functions at will, including CRT functions such as printf, and are free to use .NET Framework Platform Invoke features to call unmanaged functions inside DLLs.

C++ supports the use of ATL, MFC, SCL, and the CRT libraries as mixed assemblies compiled with /clr. These mixed libraries allow you to use all of their existing functions when your code contains a mixture of native code and MSIL code.

Performance Consideration while using Interoperability: Regardless of the interop technique used, special transition sequences, called "thunks", are required each time a managed function calls an unmanaged function, and vise-versa. These thunks are inserted automatically by the C++ compiler, but it's important to keep in mind that cumulatively, these transitions can be expensive in terms of performance.

For .NET languages such as Visual Basic and C#, the prescribed method for interoperating with native components is P/Invoke. Since P/Invoke is supported by the .NET Framework, C++ supports it as well, but C++ also provides its own interoperability support, which is referred to as C++ Interop. C++ Interop is preferred over P/Invoke because P/Invoke is not type-safe, so errors are primarily reported at run-time, but C++ Interop also has performance advantages over P/Invoke.

Both techniques require two things to happen whenever a managed function calls an unmanaged function:
  • The function call arguments are marshaled from CLR to native types
  • A managed-to-unmanaged thunk is executed
  • The unmanaged function is called (using the native versions of the arguments)
  • An Unmanaged-to-managed thunk is executed
  • The return type and any "out" or "in,out" arguments are marshaled from native to CLR types

Try it.. (In order to enable compilation for both native & managed, change the project properties (Project properties >> General >> Common Language Runtime Support >> Choose Common Language Runtime Support (/clr)))

For Extra info check the MSDN


Ramy Mahrous said...

you can also call managed code from unmanaged, if you convert the managed assembly to .tlb
good post

Roaa Mohammed said...

I heard about that, but I didn't try it myself..
Thanks Ramy for the info..

Mahmoud said...

I think what you mean in the article by C++ is "Visual C++" which is not "C++".

Roaa Mohammed said...

yes, that's wt I meant.. I think I mentioned that in "C++ supports the use of ATL, MFC, SCL, and the CRT libraries as mixed assemblies compiled with /clr."
Thanks anyway for clarification..