One of the big advantages of C++/CLI is mixing native and managed code. Using native code from C# is done with a mechanism known as platform invoke. Platform invoke is discussed in Chapter 23, “COM Interoperability.” Using native code from C++/CLI is known with the term It just works.
In a managed class, you can use both native and managed code, as you can see here. The same is true for a native class. You can mix native and managed code as well within a method.
#pragma once #include <iostream> // include this header file for cout using namespace std; // the iostream header defines the namespace std using namespace System; public ref class Managed { public: void MixNativeAndManaged() { cout << "Native Code" << endl; Console::WriteLine("Managed Code"); } };
In a managed class, you can also declare a field of a native type or a pointer to a native type. Doing the same the other way around is not possible to accomplish directly. You must take care that an instance of a managed type can be moved by the garbage collector when cleaning up memory.
For using managed classes as member within native classes, C++/CLI defines the keyword gcroot, which is defined in the header file gcroot.h. gcroot wraps a GCHandle that keeps track of a CLR object from a native reference.
#pragma once #include "gcroot.h" using namespace System; public ref class Managed { public: Managed() { } void Foo() { Console::WriteLine("Foo"); } }; public class Native { private: gcroot<Managed^> m_p; public: Native() { m_p = gcnew Managed(); } void Foo() { m_p->Foo(); } };