How to convert C++/CLI string to const char*
<p>I've got a C++/CLI DLL I plan to use as an adapter between my C# DLL and native C++ clients. I need to pass strings in both directions. The adapter is compiled with VS2013 but needs to support clients built with VS2008 so I'm using const char* in the API. But what I've got isn't working even when both are VS2013-built.</p>

<p>Elsewhere, I found advice to use msclr\marshal.h, so I created:</p>

<pre><code>using namespace msclr::interop;
System::String^ ToCliString(const char* s)
{
    System::String ^result = marshal_as&lt;System::String^&gt;(s);
    return result;
}    
const char* ToCppString(System::String^ s)
{
    msclr::interop::marshal_context context;
    const char* result = context.marshal_as&lt;const char*&gt;(s);
    return result;
}
</code></pre>

<p>To test these, I created a round-trip conversion method in my C++/CLI DLL:</p>

<pre><code>const char* Foo(const char *cstar)
{
    System::String^ cli = ::ToCliString(cstar);

    if (cli == "abc")
    {
        MessageBox::Show("const char* -&gt; CLI: OK");
    }

    const char* cstar2 = ::ToCppString(cli);

    if (std::strcmp(cstar2, "abc") == 0)
    {
        MessageBox::Show("CLI -&gt; const char*: OK");
    }
    else if (std::strcmp(cstar2, "") == 0)
    {
        MessageBox::Show("ToCppString returned empty string");
    }
    else
    {
        MessageBox::Show("ToCppString returned something else");
    }

    return cstar2;
}
</code></pre>

<p>When the native C++ client calls Foo("abc"), the 1st message gets displayed, the "returned something else" message gets displayed and the client receives junk (îþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþÞ›vÚ§). So it would seem my 2nd conversion is not working.</p>

<p><strong><em>UPDATE</em></strong></p>

<p>Here's the final solution I used.</p>

<p>I used zneaks' advice to marshall to std::string and PaulMcKenzie's advice to pass a caller-allocated char* instead of returning const char*. Thank you both.</p>

<pre><code>void ToCppString(System::String^ input, char* output)
{
    std::string temp= marshal_as&lt;std::string&gt;(input);
    strcpy(output, temp.c_str());
}

void Foo(const char* input, char* output)
{
    System::String^ cli = ::ToCliString(input);
    ::ToCppString(cli, output);
}
</code></pre>