C ++ .NET конвертировать System :: String в std :: string - PullRequest
51 голосов
/ 19 августа 2009

Как конвертировать System :: String в std :: string в C ++ .NET?

Ответы [ 6 ]

63 голосов
/ 19 августа 2009

Существует более чистый синтаксис, если вы используете последнюю версию .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;
}

Это также дает вам лучшую очистку перед лицом исключений.

Существует статья MSDN для различных других преобразований

27 голосов
/ 23 апреля 2010

И в ответ на «более легкий путь» в более поздних версиях 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;
}

6 голосов
/ 25 декабря 2015

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

Или используйте его в более компактном синтаксисе:

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;
}
6 голосов
/ 19 августа 2009
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;
  }
4 голосов
/ 17 апреля 2013

У меня было слишком много неоднозначных ошибок с указанными выше ответами (да, я нуб C ++)

Это сработало для меня при отправке строки из C # в C ++ CLI

C #

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

C ++ CLI

функция:

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

функция, которая работает от преобразования 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;
}

В ДАЛЬНЕЙШЕМ ИССЛЕДОВАНИИ, кажется, что это чище и безопаснее.

Я переключился на использование этого метода.

std::string Utils::ToUnmanagedString(String^ stringIncoming)
{
   std::string unmanagedString = marshal_as<std::string>(stringIncoming);
   return unmanagedString;
}
0 голосов
/ 15 декабря 2015

Создание компонента среды выполнения Windows, который вы можете использовать:

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