2

I found this really nice piece of code that converts a string to a System:String^ as in:

System::String^ rtn = gcnew String(move.c_str());  // 'move' here is the string

I'm passing rtn back to a C# program. Anyways, inside the function where this code exists, I'm passing in a System::String^. I also found some code to convert a System:String^ to a string using the following code:

pin_ptr<const wchar_t> wch = PtrToStringChars(cmd);  // 'cmd' here is the System:String          
size_t convertedChars = 0;
size_t  sizeInBytes = ((cmd->Length + 1) * 2);
errno_t err = 0;
char *ch = (char *)malloc(sizeInBytes);

err = wcstombs_s(&convertedChars,ch, sizeInBytes,wch, sizeInBytes);

Now I can use 'ch' as a string.

This, however, seems to be alot more work than converting the other way using the gcnew. So, at last my question is, is there something out there that will convert a System::String^ to string using a similar fashion as with the gcnew way?

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
David
  • 131
  • 3
  • 6
  • They make you do more work to intentionally do something nasty like that. At least convert to utf8 if you have to, UTF8Encoding::GetBytes(). – Hans Passant May 30 '11 at 18:28

2 Answers2

10

Use VC++'s marshaling library: Overview of Marshaling in C++

#include <msclr/marshal_cppstd.h>

// given System::String^ mstr
std::string nstr = msclr::interop::marshal_as<std::string>(mstr);
ildjarn
  • 62,044
  • 9
  • 127
  • 211
  • Holy crap, thats sweet. Thanks Ill give it a go. – David May 30 '11 at 18:17
  • How about clean up. As per link "Marshaling requires a context only when you marshal from managed to native data types and the native type you are converting to does not have a destructor for automatic clean up." Say this method is invoked from native code, will it be cleaned? std::string getItem() { String^ result = "Some val"; result += "."; return msclr::interop::marshal_as(result); } – harsha Oct 01 '13 at 11:15
  • 2
    @harsha : `std::string` has a destructor that frees its internal allocations, so that code is perfectly safe. – ildjarn Oct 01 '13 at 12:04
0

this could be useful:

wchar_t *str = "Hi StackOverflow"; //native
String^ mstr= Marshal::PtrToStringAnsi((IntPtr)str); // native to safe managed
wchar_t* A=( wchar_t* )Marshal::StringToHGlobalAnsi(mstr).ToPointer(); // return back to native 

don't forget using namespace System::Runtime::InteropServices;

Aan
  • 12,247
  • 36
  • 89
  • 150
  • 3
    Because this method allocates the unmanaged memory required for a string, always free the memory by calling FreeHGlobal. – Sam Trost Jun 09 '11 at 15:56