I tried writing a sample to use managed C++ to interact with managed code and here is my learning. I created the following managed C++ code to wrap existing FLAT API’s in a class that can be called form C#.

Managed C++ code:

#using <mscorlib.dll>

#include <vcclr.h>

using namespace System;

#include <stdio.h>

#include <wchar.h>

 

__declspec(dllexport) void NativeFlatMethod(const wchar_t *szParam)

{

      wprintf(L"%s \n", szParam);

}

 

__gc public class FlatAPIWrapper

{

public:

      static void NativeFlatMethodWrapper(System::String *szParam)

      {

            const wchar_t __pin *pChar = PtrToStringChars(szParam);

            NativeFlatMethod(pChar);

      }

};

Copy the above code to native.cpp and compile it as below

Cl /LD /CLR:oldsyntax native.cpp

You can ildasm the resultant assembly and see its contents. Now we want to write a C# executable that can consume the native-managed assembly that we compiled here.

 

Managed code:

using System;

using System.Runtime.InteropServices;

class Program

{

    static void Main()

    {

        FlatAPIWrapper.NativeFlatMethodWrapper("FLAT API called through Managed C++ wrapper");

    }

}    

 

Copy the above code to managed.cs and compile it as below

csc  /r:native.dll managed.cs

This will produce managed.exe. Copy the native.dll.manifest to managed.exe.manifest and execute the executable. 

There are multiple ways managed code can interact with native code. This is one such way. The others are through interop and writing unsafe code in C# itself. Interacting with C++ libraries using PInvoke is extremely difficult. The only good way to achieve this will be to write managed C++ or FLAT API wrappers that can be consumed in C# using PInvoke. I will write about these soon.