What is the best way to convert between char* and System::String in C++/CLI
68,729
Solution 1
There's a good overview here (this marshaling support added for VS2008): http://www.codeproject.com/KB/mcpp/OrcasMarshalAs.aspx
Solution 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);
Related videos on Youtube
Author by
Brian Stewart
Updated on July 09, 2022Comments
-
Brian Stewart almost 2 years
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"?
-
Anthony Serdyukov about 14 years+1, System::String constructor also takes length and encoding!
-
Ben Voigt over 12 years
Marshal::StringToHGlobalAnsi
is a poor option compared tomarshal_context
(as mentioned by Matthew), which uses RAII to automatically free the buffer. Not to mention that the name is totally wrong, it doesn't return anHGLOBAL
at all. -
Patrick.SE about 12 yearsProbably have to Marshal::FreeHGlobal(IntPtr((void*)chars)); it
-
dko about 12 years@Pat yes sorry I should have updated this after this. I did get it working well now. Moving it to .NET increased the performance of this app by 3x. Even marshaling things around.
-
gatopeich over 11 yearsThanks, but that is a lengthy explanation. This goes more to the point:
#include <msclr\marshal.h> // marshal_context context; // my_c_string = context.marshal_as<const char*>(my_csharp_string);
-
Mugen about 6 yearsFor those who wonder, the full namespace for context is
msclr::interop::marshal_context
-
Dewey Vozel over 5 yearsYour example does not work for me in C++/CLI using .NET 4.6.1. There is no System::String constructor that takes a char*... only signed char* or wchar_t*
-
Ben Straub over 5 yearsIt's been a while since I've been in this world, but I believe this should still work. According to the docs at docs.microsoft.com/en-us/cpp/windows/…, you should still be able to
gcnew
a string with achar *
string as the argument. Maybe you can cast tosigned char *
? -
Menace over 3 yearsFrom my experience the pointer also has no nul terminator. You need to use clistr.Length to know how long it is.