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

Ami*_*mer 53 .net c++ string marshalling

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

Col*_*ill 65

如果您使用的是最新版本的.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;
}
Run Code Online (Sandbox Code Playgroud)

这也可以在异常情况下为您提供更好的清理.

有一篇msdn文章可用于其他各种转换


小智 28

并且为了响应更高版本的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;
}
Run Code Online (Sandbox Code Playgroud)

  • 文章说如果本机类型没有析构函数来进行自己的清理,那么只需要一个上下文.那么,在`std :: string`的情况下,这需要吗? (3认同)
  • `std :: string`不需要上下文.只有在从包装类型编组到未包装类型(即原始指针)时才需要上下文.如[C++中的编组概述](http://msdn.microsoft.com/en-us/library/bb384865.aspx)中所列,只有三个需要上下文的实例. (2认同)

Spe*_*ort 6

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;
  }
Run Code Online (Sandbox Code Playgroud)

  • 这是较旧的语法.我更喜欢科林建议的那个. (2认同)

Yoc*_*mer 6

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

编译多字节字符集 Visual Studio时,Win API采用UTF8(实际上Windows编码为Windows-28591).
编译Unicode字符集时, Visual Studio和Win API采用UTF16.

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

我们的想法是决定std::wstring 始终代表UTF16.
并且std::string 始终代表UTF8.

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

或者使用更紧凑的语法:

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;
}
Run Code Online (Sandbox Code Playgroud)