C++/CLI Converting from System::String^ to std::string

匿名 (未验证) 提交于 2019-12-03 02:12:02

问题:

Can someone please post a simple code that would convert,

System::String^ 

To,

C++ std::string

I.e., I just want to assign the value of,

String^ originalString; 

To,

std::string newString; 

回答1:

Check out System::Runtime::InteropServices::Marshal::StringToCoTaskMemUni() and its friends.

Sorry can't post code now; I don't have VS on this machine to check it compiles before posting.



回答2:

Don't roll your own, use these handy (and extensible) wrappers provided by Microsoft.

For example:

#include   System::String^ managed = "test"; std::string unmanaged = msclr::interop::marshal_as<:string>(managed); 


回答3:

You can easily do this as follows

#include   System::String^ xyz="Hi boys";   std::string converted_xyz=msclr::interop::marshal_as( xyz); 


回答4:

This worked for me:

#include  #include  #include  //.. using namespace msclr::interop; //.. System::String^ clrString = (TextoDeBoton); std::string stdString = marshal_as<:string>(clrString); //String^ to std //System::String^ myString = marshal_as<:string>(MyBasicStirng); //std to String^ prueba.CopyInfo(stdString); //MyMethod //.. //Where: String^ = TextoDeBoton; //and stdString is a "normal" string; 


回答5:

Here are some conversion routines I wrote many years ago for a c++/cli project, they should still work.

void StringToStlWString ( System::String const^ s, std::wstring& os)     {         String^ string = const_cast(s);         const wchar_t* chars = reinterpret_cast((Marshal::StringToHGlobalUni(string)).ToPointer());         os = chars;         Marshal::FreeHGlobal(IntPtr((void*)chars));      }     System::String^ StlWStringToString (std::wstring const& os) {         String^ str = gcnew String(os.c_str());         //String^ str = gcnew String("");         return str;     }      System::String^ WPtrToString(wchar_t const* pData, int length) {         if (length == 0) {             //use null termination             length = wcslen(pData);             if (length == 0) {                 System::String^ ret = "";                 return ret;             }         }          System::IntPtr bfr = System::IntPtr(const_cast(pData));         System::String^ ret = System::Runtime::InteropServices::Marshal::PtrToStringUni(bfr, length);         return ret;     }      void Utf8ToStlWString(char const* pUtfString, std::wstring& stlString) {         //wchar_t* pString;         MAKE_WIDEPTR_FROMUTF8(pString, pUtfString);         stlString = pString;     }      void Utf8ToStlWStringN(char const* pUtfString, std::wstring& stlString, ULONG length) {         //wchar_t* pString;         MAKE_WIDEPTR_FROMUTF8N(pString, pUtfString, length);         stlString = pString;     } 


回答6:

I spent hours trying to convert a windows form listbox ToString value to a standard string so that I could use it with fstream to output to a txt file. My Visual Studio didn't come with marshal header files which several answers I found said to use. After so much trial and error I finally found a solution to the problem that just uses System::Runtime::InteropServices:

void MarshalString ( String ^ s, string& os ) {    using namespace Runtime::InteropServices;    const char* chars =        (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();    os = chars;    Marshal::FreeHGlobal(IntPtr((void*)chars)); }  //this is the code to use the function: scheduleBox->SetSelected(0,true); string a = "test"; String ^ c = gcnew String(scheduleBox->SelectedItem->ToString()); MarshalString(c, a); filestream 

And here is the MSDN page with the example: http://msdn.microsoft.com/en-us/library/1b4az623(v=vs.80).aspx

I know it's a pretty simple solution but this took me HOURS of troubleshooting and visiting several forums to finally find something that worked.



回答7:

I found an easy way to get a std::string from a String^ is to use sprintf().

char cStr[50] = { 0 }; String^ clrString = "Hello"; if (clrString->Length 

No need to call the Marshal functions!

UPDATE Thanks to Eric, I've modified the sample code to check for the size of the input string to prevent buffer overflow.



回答8:

C# uses the UTF16 format for its strings.
So, besides just converting the types, you should also be conscious about the string's actual format.

When compiling for Multi-byte Character set Visual Studio and the Win API assumes UTF8 (Actually windows encoding which is Windows-28591 ).
When compiling for Unicode Character set Visual studio and the Win API assume UTF16.

So, you must convert the string from UTF16 to UTF8 format as well, and not just convert to std::string.
This will become necessary when working with multi-character formats like some non-latin languages.

The idea is to decide that std::wstring always represents UTF16.
And std::string always represents UTF8.

This isn't enforced by the compiler, it's more of a good policy to have.

#include "stdafx.h" #include   #include   using namespace System;  int main(array<:string> ^args) {     System::String^ managedString = "test";      msclr::interop::marshal_context context;      //Actual format is UTF16, so represent as wstring     std::wstring utf16NativeString = context.marshal_as<:wstring>(managedString);       //C++11 format converter     std::wstring_convert<:codecvt_utf8_utf16>> convert;      //convert to UTF8 and std::string     std::string utf8NativeString = convert.to_bytes(utf16NativeString);      return 0; } 

Or have it in a more compact syntax:

int main(array<:string> ^args) {     System::String^ managedString = "test";      msclr::interop::marshal_context context;     std::wstring_convert<:codecvt_utf8_utf16>> convert;      std::string utf8NativeString = convert.to_bytes(context.marshal_as<:wstring>(managedString));      return 0; } 


回答9:

I like to stay away from the marshaller.

Using CString newString(originalString); 

Seems much cleaner and faster to me. No need to worry about creating and deleting a context.



回答10:

// I used VS2012 to write below code-- convert_system_string to Standard_Sting

        #include "stdafx.h"         #include          #include            using namespace System;         using namespace Runtime::InteropServices;            void MarshalString ( String^ s, std::string& outputstring )         {              const char* kPtoC =  (const char*) (Marshal::StringToHGlobalAnsi(s)).ToPointer();                                                                    outputstring = kPtoC;              Marshal::FreeHGlobal(IntPtr((void*)kPtoC));           }             int _tmain(int argc, _TCHAR* argv[])         {              std::string strNativeString;                String ^ strManagedString = "Temp";               MarshalString(strManagedString, strNativeString);                std::cout 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!