Introduction

The natural choice today for a programming language for writing a new piece of software in the Microsoft environment is C#. For various reasons, some parts of the project may be written in other languages (existing packages, third party, performance, etc.). In this short article, I'll suggest what seems to me like a good, easy to manage, alternative for interoperation between managed and unmanaged code.

The .NET Environment

Microsoft got jealous of Java and created its own virtual machine, the CLR. Compilation of code in C# generates a machine code suitable for this virtual machine. Microsoft went one step further so that the code of other languages, such as C++, compiles to the same machine language. It is possible therefore to call from a DLL or an executable in C# to a DLL in C++, and vise versa. Each team uses its preferred programming language and it all fits together in the linkage.

Managed Code vs. Unmanaged Code

Code that runs in the .NET environment is called a managed code. Code that runs as in old days is called unmanaged code. The "management" brings a lot of advantages such as "garbage collection" of memory that was allocated but will never be used again. The disadvantages of the "management" are lesser performance, and the difficulty to interact with existing libraries in unmanaged code.

IJW

Microsoft brings a friendly solution which exists to the best of my knowledge only for C++. The solution enables calling from managed code to unmanaged code and vise versa, It Just Works! The only limitation is that there will be no use of "managed" data types in the unmanaged code. Hence it is possible to pass basic data types such as int, double, and data types that were defined as "not managed". In order to use that feature, we'll create the new DLL, or executable, as a C++ project for CLR (managed), and then we'll surround unmanaged code with:

#pragma unmanaged
#pragma managed

Use Case Example and a Code Snippet

In a project, I defined some classes in C# and created a DLL to hold those. The classes were intended to present a configuration for a real-time program. We decided that the real-time loops and logic will be written in unmanaged C++ code. I've created another DLL which was written in C++ and was also using the CLR. That way the DLL written in C++ could reference the DLL written in C# and use the classes representing the configuration. The program itself wrapping everything was written in C#. Hence the program is familiar with the classes in the C# DLL. It passes them to the C++ DLL, which is also familiar with those classes. There is still one problem left. We need to translate "managed" data types to "unmanaged" data types, in order to call unmanaged code. The work involved here is either trivial or Sisyphean, yet it will be a no-brainer. There is another alternative, which is working with unmanaged data types throughout both the unmanaged and managed code. I suggest that explicit translation is more convenient and self explanatory and is done at the last moment on the border between managed code and unmanaged code.

Comments and Discussions

It would be nice if you could have post a sample project for better explanations. I have unsuccessfully been trying since I read your article. But it is pretty nice, mixing managed and unmanaged code this way. Can such an approach be used to create wrappers for legacy code without actually having to redefine custom made struct? Thanks in advance!

Dear hotbyte, please forgive me for not posting a project. The simplest way to test the C++ IJW feature is to create a new C++ Console Application project for the CLR. After including a .h and a .cpp files as above, from the main program create a new CConfig object, passing in its ctor an integer, a double, and a string. Then call the doTheStuff method.

Once you have this working, try to create new a C++ DLL project, also for CLR, containing the CConfig class and all of the code in the example (this project will not include a main program). Now try to create a new C# Console Application project. The C# Console Applicaion will reference the C++ DLL and will do the same as above (Create a new CConfig object, and then call the doTheStuff).

Regarding the second part of your message, if we choose to continue working with the structs from the legacy code, note that for example, if the structs contain char array as a string, you are forced to continue work with functions such as strcmp, etc. instead of working with first class instances of String.

When you have more managed <-> UnManaged Transitions, for example if you are using to much P/Invoke'ing', then the performance of the application will go for a toss. A simple example is say taking a screen shot programatically or creating a movie from contnuous screen shots (live). In this case instead of using P/Invoke, youcan simply use IJW. And ya, I know one an even implement every thing in unmanaged DLL and can just do a single P/Invoke, depends...

But anyway using IJW, you are at the best of two worlds....C++ and C++/CLI(managed C++/.NET). You can simply use best from both yet in same class....