Passing managed strings to unmanaged strings

I've spent a great deal of time tying figuring out how to pass c# strings to an unmanaged c++ program. Therefore, here is a little what I discovered how it can be done.

C# strings don't work the same as c++ strings. In C++ a string is referenced by a pointer - something C# does not do. In C#, types are either value types or reference types (placed on the heap) and aren't accessible as they are in unmanaged space.

Suppose you want to call a method that was written in C++ that takes in string values of type LPCWSTR. You add C++ Class Library DLL to your project. For example, here's the C++ part it:
void PassStrings(LPCWSTR string1,LPCWSTR string2)
{...}
Now, you want to call this from C#. Simply doing this: PassStrings(s1, s1) where s1 and s2 are string types won't work. It turns out (at least what I discovered) there is a way by using the "StringToHGlobalUni" method, and converting it to a Pointer using ToPointer(). Be sure to add using System.Runtime.InteropServices;
unsafe{
char* a1 = (char *)Marshal.StringToHGlobalUni(s1).ToPointer();
char* a2 = (char *)Marshal.StringToHGlobalUni(s2).ToPointer();
classobj.PassStrings(a1, a2);
}
Also use the "unsafe" keyword along with the unsafe compiler option.
This at least works for LPCWSTR types. For char* or String^ types will probably need some modifications.
The code below taken from support.microsoft.com shows some methods done on the c++ side:

//compiler option: cl /clr  
#include <vcclr.h>
#include <atlstr.h>
#include <stdio.h>
#using <mscorlib.dll>
using namespace System;
using namespace System::Runtime::InteropServices;

int _tmain(void)
{
       System::String * str = S"Hello world\n";

    //method 1
    const __wchar_t __pin * str1 = PtrToStringChars(str);
    wprintf(str1);    

    //method 2
    char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(str);
    printf(str2);
    Marshal::FreeHGlobal(str2);

    //method 3
    CString str3(str); ntf(str3);

    return 0;
}

By Frank Neubecker