C++/CLI从System :: String ^转换为std :: string

siv*_*udh 87 string managed-c++ c++-cli

有人可以发一个简单的代码,可以转换,

System::String^
Run Code Online (Sandbox Code Playgroud)

至,

C++ std::string

即,我只想分配值,

String^ originalString;
Run Code Online (Sandbox Code Playgroud)

至,

std::string newString;
Run Code Online (Sandbox Code Playgroud)

tra*_*los 144

不要自己滚动,使用Microsoft提供的这些方便(和可扩展)包装器.

例如:

#include <msclr\marshal_cppstd.h>

System::String^ managed = "test";
std::string unmanaged = msclr::interop::marshal_as<std::string>(managed);
Run Code Online (Sandbox Code Playgroud)

  • 虽然这很方便,但它完全缺乏适当的编码支持.另见我的问题:http://stackoverflow.com/questions/18894551/string-marshalling-with-marshal-as-and-encodings.我的假设是marshal_as将Unicode字符串转换为std :: string中的ACP. (4认同)
  • 对于这个有用的链接,这个提示为我节省了很多代码.作为旁注:模板/类在#include <msclr \\*.h>(例如#include <msclr\marshal.h>)和msclr :: interop命名空间中,请参阅http://上的示例msdn.microsoft.com/de-de/library/vstudio/bb384859(v=vs.90).aspx) (2认同)

Mar*_*tin 38

退房System::Runtime::InteropServices::Marshal::StringToCoTaskMemUni()和它的朋友.

抱歉,现在无法发布代码; 在发布之前我没有VS在这台机器上检查它是否编译.


Sri*_*ake 38

您可以轻松地执行以下操作

#include <msclr/marshal_cppstd.h>

System::String^ xyz="Hi boys"; 

std::string converted_xyz=msclr::interop::marshal_as< std::string >( xyz);
Run Code Online (Sandbox Code Playgroud)

  • 嗯... 33赞成已经在两年多前提供的答案,几乎相同的代码行.尊重为此获得如此多的积分.;-) (6认同)

小智 20

这对我有用:

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

  • 英语翻译:"我也会回复这篇文章:p.这是我的功能." (2认同)

Ben*_*ehn 9

以下是我多年前为c ++/cli项目编写的一些转换例程,它们应该仍然有用.

void StringToStlWString ( System::String const^ s, std::wstring& os)
    {
        String^ string = const_cast<String^>(s);
        const wchar_t* chars = reinterpret_cast<const wchar_t*>((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<wchar_t*>(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;
    }
Run Code Online (Sandbox Code Playgroud)


Ion*_*316 6

我发现从String ^获取std :: string的简单方法是使用sprintf()。

char cStr[50] = { 0 };
String^ clrString = "Hello";
if (clrString->Length < sizeof(cStr))
  sprintf(cStr, "%s", clrString);
std::string stlString(cStr);
Run Code Online (Sandbox Code Playgroud)

无需调用元帅功能!

更新感谢Eric,我修改了示例代码以检查输入字符串的大小,以防止缓冲区溢出。

  • 在代码中引入缓冲区溢出漏洞只是为了避免调用专门设计用于编组字符串的函数,这是一个奇怪的决定。 (2认同)

小智 5

我花了好几个小时尝试将Windows窗体列表框ToString值转换为标准字符串,以便我可以将它与fstream一起输出到txt文件.我的Visual Studio没有附带编组头文件,我找到了几个使用的答案.经过这么多试验和错误,我终于找到了一个解决方案,解决了刚刚使用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 << a;
Run Code Online (Sandbox Code Playgroud)

这是MSDN页面的示例:http: //msdn.microsoft.com/en-us/library/1b4az623(v = vs.80).aspx

我知道这是一个非常简单的解决方案,但这需要我的故障排除和访问几个论坛,最终找到有用的东西.