HOWTO: Basic Native/Managed Code Interop

IIS7 core extensibility model supports both native and managed code as first-class citizens. So, I feel it is time for a little refresher on managed/native code interop... starting with the more popular route of how to wrap native code API for use within managed code. I am using the newer syntax introduced with .Net Framework 2.0 instead of the older, kludgy syntax.

Now, I am going to ignore the reciprocal route of calling managed code from native code for a couple of reasons:

  • It is just boiler plate COM Interop within native code after generating and registering the CCW (COM Callable Wrapper) of the managed class.
  • Why don't you just write a managed code module/handler in IIS7 to directly use that managed API?

The example illustrates how to use Managed Code to:

  • Pass a .NET String into Managed C++
  • Manipulate a .NET String in Managed C++
  • Return a .NET String from Managed C++
  • Pass in arbitrary number of args into Managed C++

Remember to use a Class Library Project for Sample.h and Sample.cpp to create a Managed C++ Wrapper around native code API, and you can use the resulting Managed Assembly from Sample.cs managed code.




#pragma once
#include <windows.h>
#include "SomeNativeAPI.h"

using namespace System;
using namespace System::Runtime::InteropServices;

namespace Sample
public ref class ManagedClass
ManagedClass( String^ name );
String^ DebugPrint( String^ format, ...array<String^>^ args );
SomeNativeType* m_pType;


#include "Sample.h"

Sample::ManagedClass::ManagedClass( String^ name )
// Convert .NET String into LPSTR for
// Native code API to use in constructor
IntPtr szName;
szName = Marshal::StringToHGlobalAnsi( name );
m_pType = new SomeNativeType( szName );
Marshal::FreeHGlobal( szName );
delete m_pType;
String^ Sample::ManagedClass::DebugPrint( String^ format, ...array<String^>^ args )
// Use Managed Code to format variable arguments as .NET String,
// convert the .NET String into Unicode String, and pass
// it to Native API
String^ formattedString = System::String::Format( format, args );
IntPtr wszFormattedString;

wszFormattedString = Marshal::StringToHGlobalUni( formattedString );
m_pType->SomeFunctionUnicode( wszFormattedString );
Marshal::FreeHGlobal( wszFormattedString );

return formattedString;


namespace Sample
class Program
static void Main( string[] args )
Sample.ManagedClass cls = new Sample.ManagedClass( "Name?" );
System.Console.WriteLine( cls.DebugPrint( "0:{0},1:{1}", "N", "V" ) );

Comments (1)
  1. David Richter says:

    The System.Runtime.InteropServices namespace defines methods that work with the CLR so that managed code can call native, raw c DLLs.The DllImport atttrubute has be marked by the namespace and the C# program callling the function uses the name of the function"

    using System;

    using System.Runtime.InteropServices;

    class Program {


    public static extern bool Beep( uint  iFreq, uint iDuration );

    static void Main() {

       bool b = Beep( 100,  100 );



    C:.NET> csc.exe /target:exe beep.cs

Comments are closed.

Skip to main content