What is the best way to convert between char* and

2019-01-06 12:24发布

问题:

What is the approved way to convert from char* to System::string and back in C++/CLI? I found a few references to marshal_to<> templated functions on Google, but it appears that this feature never made the cut for Visual Studio 2005 (and isn't in Visual Studio 2008 either, AFAIK). I have also seen some code on Stan Lippman's blog, but it's from 2004. I have also seen Marshal::StringToHGlobalAnsi(). Is there a method that is considered "best practice"?

回答1:

There's a good overview here (this marshaling support added for VS2008): http://www.codeproject.com/KB/mcpp/OrcasMarshalAs.aspx



回答2:

System::String has a constructor that takes a char*:

 using namespace system;
 const char* charstr = "Hello, world!";
 String^ clistr = gcnew String(charstr);
 Console::WriteLine(clistr);

Getting a char* back is a bit harder, but not too bad:

 IntPtr p = Marshal::StringToHGlobalAnsi(clistr);
 char *pNewCharStr = static_cast<char*>(p.ToPointer());
 cout << pNewCharStr << endl;
 Marshal::FreeHGlobal(p);


回答3:

What we did is made a C++\CLI object that held the string in unmangaed code and would give out manged copies of the item. The conversion code looks very much like what Stan has on his blog (I can't remember it exactly)(If you use his code make sure you update it to use delete[]) but we made sure that the destructor would handle releasing all the unmanged elements of the object. This is a little overblown but we didn't have leaks when we tied into legacy C++ code modules.



回答4:

I created a few helper methods. I needed to do this to move from an old Qt library to CLI String. If anyone can add onto this and tell me if it seems like I have a memory leak and what I can do to fix it, I would be most appreciative.

void MarshalString (  String ^ s, wstring& os ) {
    using namespace Runtime::InteropServices;
    const wchar_t* char = (const wchar_t*)(Marshal::StringToHGlobalUni(s)).ToPointer();
    os = char;
}
QString SystemStringToQt( System::String^ str)
{
    wstring t;
    MarshalString(str, t);
    QString r = QString::fromUcs2((const ushort*)t.c_str());
    return r;
}


回答5:

One additional link to a summary of possible ways:

http://support.microsoft.com/?kbid=311259