C++/CLI 从 System::String^ 转换为 std::string
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/946813/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++/CLI Converting from System::String^ to std::string
提问by sivabudh
Can someone please post a simple code that would convert,
有人可以发布一个可以转换的简单代码,
System::String^
To,
到,
C++ std::string
C++ std::string
I.e., I just want to assign the value of,
即,我只想分配的值,
String^ originalString;
To,
到,
std::string newString;
采纳答案by Martin
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 在发布之前检查它是否编译。
回答by tragomaskhalos
回答by Sriwantha Attanayake
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);
回答by Alejandro Perea
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;
回答by Ben Schwehn
Here are some conversion routines I wrote many years ago for a c++/cli project, they shouldstill 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;
}
回答by Ionian316
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!
无需调用 Marshal 函数!
UPDATEThanks to Eric, I've modified the sample code to check for the size of the input string to prevent buffer overflow.
更新感谢 Eric,我修改了示例代码以检查输入字符串的大小以防止缓冲区溢出。
回答by Joe
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 没有附带 marshal 头文件,我发现有几个答案说要使用这些文件。经过如此多的反复试验,我终于找到了只使用 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.
我知道这是一个非常简单的解决方案,但这花了我数小时的故障排除和访问几个论坛,最终找到了一些有效的方法。
回答by Yochai Timmer
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 setVisual Studio and the Win API assumes UTF8 (Actually windows encoding which is Windows-28591).
When compiling for Unicode Character setVisual 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
alwaysrepresents UTF16.
And std::string
alwaysrepresents 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;
}
回答by LL.
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.
对我来说似乎更干净、更快。无需担心创建和删除上下文。
回答by Praveer Kumar
// I used VS2012 to write below code-- convert_system_string to Standard_Sting
// 我用VS2012写了下面的代码——convert_system_string to 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;
}