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

C++/CLI从System::String^转换为std::String,string,c++-cli,managed-c++,String,C++ Cli,Managed C++,有人能发布一个简单的代码来转换 System::String^ 对, C++std::string 也就是说,我只想赋值 String^ originalString; 对, 查看System::Runtime::InteropServices::Marshal::StringToCoTaskMemUni()及其好友 抱歉,现在无法发布代码;我在这台机器上没有VS来检查它在发布之前的编译情况。这里是我多年前为c++/cli项目编写的一些转换例程,它们应该仍然可以工作 void StringT

有人能发布一个简单的代码来转换

System::String^
对,

C++
std::string

也就是说,我只想赋值

String^ originalString;
对,


查看
System::Runtime::InteropServices::Marshal::StringToCoTaskMemUni()
及其好友


抱歉,现在无法发布代码;我在这台机器上没有VS来检查它在发布之前的编译情况。

这里是我多年前为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;
    }
void StringToStlWString(系统::字符串常量^s,标准::wstring&os)
{
字符串^String=const\u cast;
const wchar_t*chars=reinterpret_cast((Marshal::StringToHGlobalUni(string)).ToPointer());
os=字符;
marshall::FreeHGlobal(IntPtr((void*)chars));
}
系统::字符串^StlWStringToString(std::wstring const&os){
String^str=gcnewstring(os.c_str());
//字符串^str=gcnew字符串(“”);
返回str;
}
系统::字符串^WPtrToString(wchar\u t const*pData,int-length){
如果(长度==0){
//使用空终止
长度=wcslen(pData);
如果(长度==0){
系统::字符串^ret=“”;
返回ret;
}
}
System::IntPtr bfr=System::IntPtr(const_cast(pData));
System::String^ret=System::Runtime::InteropServices::Marshal::PtrToStringUni(bfr,长度);
返回ret;
}
void Utf8ToStlWString(字符常量*pUtfString,std::wstring和stlString){
//wchar_*pString;
从UTF8(pString,pUtfString)生成宽ptr_;
stlString=pString;
}
void Utf8ToStlWStringN(字符常量*pUtfString,标准::wstring和stlString,ULONG长度){
//wchar_*pString;
从utf8n(pString,pUtfString,length)生成宽ptr;
stlString=pString;
}
不要使用自己的包装,请使用Microsoft提供的方便(可扩展)的包装

例如:

#include <msclr\marshal_cppstd.h>

System::String^ managed = "test";
std::string unmanaged = msclr::interop::marshal_as<std::string>(managed);
#包括
系统::字符串^managed=“test”;
std::string unmanaged=msclr::interop::marshal_as(托管);
这对我很有用:

#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;
#包括
#包括
#包括
//..
使用名称空间msclr::interop;
//..
系统::字符串^clrString=(TextoDeBoton);
std::string stdString=marshal_as(clrString)//字符串^to std
//System::String ^myString=marshal_as(mybasicstirn)//标准到字符串^
prueba.CopyInfo(标准字符串)//我的方法
//..
//其中:String^=TextoDeBoton;
//stdString是一个“普通”字符串;

我花了数小时试图将windows窗体列表框转换为标准字符串,以便将其与fstream一起使用以输出到txt文件。我的VisualStudio没有提供封送头文件,我发现有几个答案说是使用封送头文件。经过这么多的尝试和错误,我终于找到了一个解决问题的方法,它只使用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;
void封送处理字符串(字符串^s、字符串&os){
使用命名空间运行时::InteropServices;
常量字符*字符=
(常量字符*)(封送:StringToHGlobalAnsi(s)).ToPointer();
os=字符;
marshall::FreeHGlobal(IntPtr((void*)chars));
}
//这是使用该功能的代码:
scheduleBox->SetSelected(0,true);
字符串a=“测试”;
字符串^c=gcnew字符串(scheduleBox->SelectedItem->ToString());
编组字符串(c,a);

filestream您可以按如下方式轻松完成此操作

#include <msclr/marshal_cppstd.h>

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

std::string converted_xyz=msclr::interop::marshal_as< std::string >( xyz);
#包括
系统::字符串^xyz=“嗨男孩”;
std::string converted_xyz=msclr::interop::marshal_as(xyz);

我发现从字符串中获取std::string^的一个简单方法是使用sprintf()

char cStr[50]={0};
字符串^CLRSTING=“你好”;
如果(clrString->Length
不需要调用封送处理函数


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

我喜欢远离封送拆收器

Using CString newString(originalString);

对我来说似乎更干净更快。无需担心创建和删除上下文。

//我使用VS2012编写了以下代码——将系统字符串转换为标准字符串

        #include "stdafx.h"
        #include <iostream>
        #include <string> 

        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 << strNativeString << std::endl; 

             return 0;
        }
#包括“stdafx.h”
#包括
#包括
使用名称空间系统;
使用命名空间运行时::InteropServices;
无效封送处理字符串(字符串^s,标准::字符串和输出字符串)
{  
常量字符*kPtoC=(常量字符*)(封送:StringToHGlobalAnsi(s)).ToPointer();
outputstring=kPtoC;
元帅:FreeHGlobal(IntPtr((void*)kPtoC));
}   
int _tmain(int argc,_TCHAR*argv[]
{
std::字符串strNativeString;
字符串^strmagedstring=“Temp”;
封送字符串(strmagedstring、strNativeString);
std::coutC#使用UTF16格式作为字符串。
因此,除了转换类型之外,还应该注意字符串的实际格式

为Visual Studio和Win API编译多字节字符集时,采用UTF8(实际上是windows编码)。
Unicode字符集编译时,Visual studio和Win API采用UTF16

因此,您还必须将字符串从UTF16格式转换为UTF8格式,而不仅仅是转换为std::string。
在使用多字符格式(如某些非拉丁语言)时,这将是必要的

这样做的目的是确定
std::wstring
始终表示UTF16
std::string
始终表示UTF8

这不是由编译器强制执行的,而是一个更好的策略

#include "stdafx.h"
#include <string>
#include <codecvt>
#include <msclr\marshal_cppstd.h>

using namespace System;

int main(array<System::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<std::wstring>(managedString); 

    //C++11 format converter
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;

    //convert to UTF8 and std::string
    std::string utf8NativeString = convert.to_bytes(utf16NativeString);

    return 0;
}
#包括“stdafx.h”
#包括
#包括
#包括
使用名称空间系统;
int main(数组^args)
{
s
        #include "stdafx.h"
        #include <iostream>
        #include <string> 

        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 << strNativeString << std::endl; 

             return 0;
        }
#include "stdafx.h"
#include <string>
#include <codecvt>
#include <msclr\marshal_cppstd.h>

using namespace System;

int main(array<System::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<std::wstring>(managedString); 

    //C++11 format converter
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;

    //convert to UTF8 and std::string
    std::string utf8NativeString = convert.to_bytes(utf16NativeString);

    return 0;
}
int main(array<System::String ^> ^args)
{
    System::String^ managedString = "test";

    msclr::interop::marshal_context context;
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;

    std::string utf8NativeString = convert.to_bytes(context.marshal_as<std::wstring>(managedString));

    return 0;
}