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

时间:2022-09-01 11:35:45

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;

10 个解决方案

#1


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

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

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

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

#2


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

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

For example:

#include <msclr\marshal_cppstd.h>

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

#3


You can easily do this as follows

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

#include <msclr/marshal_cppstd.h>

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

std::string converted_xyz=msclr::interop::marshal_as< std::string >( xyz);

#4


This worked for me:

这对我有用:

#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;

#5


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

以下是我多年前为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;
    }

#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:

我花了几个小时尝试将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;

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

这是MSDN页面的示例: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().

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

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

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.

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

#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.

C#使用UTF16格式作为字符串。因此,除了转换类型之外,您还应该注意字符串的实际格式。

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.

编译多字节字符集Visual Studio时,Win API采用UTF8(实际上Windows编码为Windows-28591)。编译Unicode字符集时Visual Studio和Win API假设为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.

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

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

我们的想法是决定std :: wstring总是代表UTF16。并且std :: string总是代表UTF8。

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

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

#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;
}

Or have it in a more compact syntax:

或者使用更紧凑的语法:

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;
}

#9


I like to stay away from the marshaller.

我喜欢远离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

//我使用VS2012编写下面的代码 - convert_system_string到Standard_Sting

        #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;
        }

#1


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

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

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

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

#2


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

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

For example:

#include <msclr\marshal_cppstd.h>

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

#3


You can easily do this as follows

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

#include <msclr/marshal_cppstd.h>

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

std::string converted_xyz=msclr::interop::marshal_as< std::string >( xyz);

#4


This worked for me:

这对我有用:

#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;

#5


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

以下是我多年前为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;
    }

#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:

我花了几个小时尝试将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;

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

这是MSDN页面的示例: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().

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

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

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.

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

#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.

C#使用UTF16格式作为字符串。因此,除了转换类型之外,您还应该注意字符串的实际格式。

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.

编译多字节字符集Visual Studio时,Win API采用UTF8(实际上Windows编码为Windows-28591)。编译Unicode字符集时Visual Studio和Win API假设为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.

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

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

我们的想法是决定std :: wstring总是代表UTF16。并且std :: string总是代表UTF8。

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

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

#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;
}

Or have it in a more compact syntax:

或者使用更紧凑的语法:

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;
}

#9


I like to stay away from the marshaller.

我喜欢远离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

//我使用VS2012编写下面的代码 - convert_system_string到Standard_Sting

        #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;
        }