C++ .NET 将 System::String 转换为 std::string

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1300718/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:28:19  来源:igfitidea点击:

C++ .NET convert System::String to std::string

.netc++stringmarshalling

提问by Amish Programmer

How do you convert System::String to std::string in C++ .NET?

如何在 C++ .NET 中将 System::String 转换为 std::string?

回答by Colin Gravill

There is cleaner syntax if you're using a recent version of .net

如果您使用的是最新版本的 .net,则语法更简洁

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

#include <msclr\marshal_cppstd.h>

using namespace System;

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

    msclr::interop::marshal_context context;
    std::string standardString = context.marshal_as<std::string>(managedString);

    return 0;
}

This also gives you better clean-up in the face of exceptions.

这也可以让您在遇到异常时进行更好的清理。

There is an msdn articlefor various other conversions

一篇关于各种其他转换的msdn 文章

回答by Mike Johnson

And in response to the "easier way" in later versions of C++/CLI, you can do it without the marshal_context. I know this works in Visual Studio 2010; not sure about prior to that.

为了响应更高版本的 C++/CLI 中的“更简单的方法”,您可以在没有 marshal_context 的情况下执行此操作。我知道这在 Visual Studio 2010 中有效;在此之前不确定。



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

#include <msclr\marshal_cppstd.h>

using namespace msclr::interop;

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

    std::string standardString = marshal_as<std::string>(managedString);

    return 0;
}


回答by Spencer Ruport

stdString = toss(systemString);

  static std::string toss( System::String ^ s )
  {
    // convert .NET System::String to std::string
    const char* cstr = (const char*) (Marshal::StringToHGlobalAnsi(s)).ToPointer();
    std::string sstr = cstr;
    Marshal::FreeHGlobal(System::IntPtr((void*)cstr));
    return sstr;
  }

回答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::wstringalwaysrepresents UTF16.
And std::stringalwaysrepresents 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 <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 Tom Stickel

I had too many ambiguous errors showing up with the above answers ( yes, i'm a C++ noob)

上面的答案出现了太多模棱两可的错误(是的,我是 C++ 菜鸟)

This worked for me for sending string from C# to C++ CLI

这对我从 C# 到 C++ CLI 发送字符串有用

C#

C#

bool result;
result = mps.Import(mpsToolName);


C++ CLI

C++命令行界面

function:

功能:

bool ManagedMPS::Import(System::String^ mpsToolNameTest)
std::string mpsToolName;
mpsToolName = toStandardString(mpsToolNameTest);

function that works from converting String^ to std::string

将 String^ 转换为 std::string 的函数

static std::string toStandardString(System::String^ string)
{
 using System::Runtime::InteropServices::Marshal;
 System::IntPtr pointer = Marshal::StringToHGlobalAnsi(string);
 char* charPointer = reinterpret_cast<char*>(pointer.ToPointer());
 std::string returnString(charPointer, string->Length);
 Marshal::FreeHGlobal(pointer);
 return returnString;
}

ON FURTHER RESEARCH, it appears that this is cleaner and safer.

在进一步研究中,这似乎更清洁、更安全。

I switched to using this method instead.

我改用这种方法。

std::string Utils::ToUnmanagedString(String^ stringIncoming)
{
   std::string unmanagedString = marshal_as<std::string>(stringIncoming);
   return unmanagedString;
}

回答by Flayn

Creating a Windows Runtime Component you can use:

创建您可以使用的 Windows 运行时组件:

String^ systemString = "Hello";
std::wstring ws1(systemString ->Data());
std::string standardString(ws1.begin(), ws1.end());