Click here to Skip to main content
15,860,943 members
Articles / Containers / Virtual Machine

Moving Data between Managed Code and Unmanaged Code – Alternative Using C++ and IJW

Rate me:
Please Sign up or sign in to vote.
3.75/5 (5 votes)
15 Apr 2009CPOL3 min read 42.1K   18   5
Moving data between Managed Code and Unmanaged Code – Alternative using C++ and IJW

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:

C++
#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.

Following is a code snippet:

*.h File (C++)

C++
public ref class CConfig 
{ 
public: 
    CConfig (int _a, String ^_str, double _d); 
    void doTheStuff (); 
    int m_a; 
    String ^m_str; 
    double m_d; 
};

*.cpp File

C++
#include <stdio.h> 
#include <stdlib.h> 
#include <vcclr.h> 
#include <iostream> 
void someMoreInManaged () 
{ 
    Console::WriteLine("C++ Managed – someMoreInManaged"); 
} 

#pragma unmanaged 
void doTheStuff1 (int _a, double _d, const wchar_t* const _str) { 
    std::cout << "C++ unmanaged – doTheStuff1" << std::endl; 
    std::cout << _a << _std::endl; 
    printf_s("%S\n", _str); 
    std::cout << _d << _std::endl; 
    someMoreInManaged(); 
} 

#pragma managed 
CConfig::CConfig 
(int _a, String ^_str, double _d) { 
    m_a = _a; 
    m_str = _str; 
    m_d = _d; 
} 
void CConfig::doTheStuff () { 
    Console::WriteLine("C++ Managed – doTheStuff"); 
    // Pin memory so GC can't move it while 
    // native function is called – MSDN documentation wchar_t <-> String 
    pin_ptr<const wchar_t> wch = PtrToStringChars(m_str); 
    doTheStuff1 (m_a,m_d,wch); 
}

History

  • 15th April, 2009: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 2 Pin
SuperJames742-Oct-09 5:35
SuperJames742-Oct-09 5:35 
Questionmore info Pin
hotbyte6415-Apr-09 12:13
hotbyte6415-Apr-09 12:13 
AnswerRe: more info Pin
Oren Zeev-Ben-Mordehai15-Apr-09 13:31
Oren Zeev-Ben-Mordehai15-Apr-09 13:31 
GeneralRe: more info Pin
hotbyte6415-Apr-09 16:01
hotbyte6415-Apr-09 16:01 
GeneralRe: more info Pin
AnandChavali18-Apr-09 2:35
AnandChavali18-Apr-09 2:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.