Преобразование из System::String в Char в Visual C++

В этой статье описывается несколько способов преобразования из System::String* в char* с помощью управляемых расширений в Visual C++.

Исходная версия продукта: Visual C++
Исходный номер базы знаний: 311259

Сводка

В этой статье рассматриваются следующие пространства имен библиотеки классов Microsoft платформа .NET Framework:

  • System::Runtime::InteropServices
  • Msclr::interop

В этой статье рассматриваются несколько способов преобразования из System::String* в char* с помощью следующего:

  • Управляемые расширения для C++ в Visual C++ .NET 2002 и Visual C++ .NET 2003
  • C++/CLI в Visual C++ 2005 и Visual C++ 2008

Способ 1

PtrToStringChars предоставляет внутренний указатель на фактический String объект. При передаче этого указателя в вызов неуправляемой функции необходимо сначала закрепить указатель, чтобы убедиться, что объект не перемещается во время асинхронного процесса сборки мусора:

//#include <vcclr.h>
System::String * str = S"Hello world\n";
const __wchar_t __pin * str1 = PtrToStringChars(str);
wprintf(str1);

Способ 2

StringToHGlobalAnsi копирует содержимое управляемого String объекта в собственную кучу, а затем преобразует его в формат ANSI на лету. Этот метод выделяет необходимую собственную память кучи:

//using namespace System::Runtime::InteropServices;
System::String * str = S"Hello world\n";
char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(str);
printf(str2);
Marshal::FreeHGlobal(str2);

Примечание.

В Visual C++ 2005 и Visual C++ 2008 необходимо добавить параметр компилятора поддержки среды CLR (/clr:oldSyntax), чтобы успешно скомпилировать предыдущий пример кода. Чтобы добавить параметр компилятора поддержки среды CLR, выполните следующие действия.

  1. Щелкните Проект, а затем — Свойства ProjectName.

    Примечание.

    ProjectName — это заполнитель для имени проекта.

  2. Разверните узел Свойства конфигурации, а затем щелкните Общие.

  3. В правой области щелкните , чтобы выбрать Поддержка common Language Runtime, Old Syntax (/clr:oldSyntax) в параметрах проекта поддержки среды CLR .

  4. Чтобы выполнить поиск абонентской группы для пользователя в поле Абонентская группа (телефонный контекст), нажмите кнопку Обзор.

Дополнительные сведения о параметрах компилятора в среде CLR см. на следующем веб-сайте Microsoft Developer Network (MSDN):

/clr (компиляция среды CLR)

Эти действия применимы ко всей статье.

Способ 3

Класс VC7 CString имеет конструктор, который принимает управляемый указатель String и загружает CString с содержимым:

//#include <atlstr.h>
System::String * str = S"Hello world\n";
CString str3(str);
printf(str3);

Способ 4

Visual C++ 2008 представляет класс справки marshal_as<T> маршал и вспомогательный marshal_context() класс маршал.

//#include <msclr/marshal.h>
//using namespace msclr::interop;
marshal_context ^ context = gcnew marshal_context();
const char* str4 = context->marshal_as<const char*>(str);
puts(str4);
delete context;

Примечание.

Этот код не компилируется с помощью управляемых расширений для C++ в Visual C++ .NET 2002 или Visual C++ .NET 2003. В нем используется новый синтаксис C++/CLI, представленный в Visual C++ 2005, и новый код пространства имен msclr, представленный в Visaul C++ 2008. Для успешной компиляции этого кода необходимо использовать параметр компилятора /clr C++ в Visual C++ 2008.

Пример кода управляемых расширений для C++ (Visual C++ 2002 или Visual C++ 2003)

//compiler option: cl /clr
#include <vcclr.h>
#include <atlstr.h>
#include <stdio.h>
#using <mscorlib.dll>
using namespace System;
using namespace System::Runtime::InteropServices;

int _tmain(void)
{
    System::String * str = S"Hello world\n";

    //method 1
    const __wchar_t __pin * str1 = PtrToStringChars(str);
    wprintf(str1);

    //method 2
    char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(str);
    printf(str2);
    Marshal::FreeHGlobal(str2);

    //method 3
    CString str3(str);
    wprintf(str3);

    return 0;
}

Пример кода C++/CLI (Visual C++ 2005 и Visual C++ 2008)

//compiler option: cl /clr

#include <atlstr.h>
#include <stdio.h>
#using <mscorlib.dll>

using namespace System;
using namespace System::Runtime::InteropServices;

#if _MSC_VER > 1499 // Visual C++ 2008 only
#include <msclr/marshal.h>
using namespace msclr::interop;
#endif

int _tmain(void)
{
    System::String ^ str = "Hello world\n";

    //method 1
    pin_ptr<const wchar_t> str1 = PtrToStringChars(str);
    wprintf(str1);

    //method 2
    char* str2 = (char*)Marshal::StringToHGlobalAnsi(str).ToPointer();
    printf(str2);
    Marshal::FreeHGlobal((IntPtr)str2);

    //method 3
    CString str3(str);
    wprintf(str3);

    //method 4
    #if _MSC_VER > 1499 // Visual C++ 2008 only
    marshal_context ^ context = gcnew marshal_context();
    const char* str4 = context->marshal_as<const char*>(str);
    puts(str4);
    delete context;
    #endif

    return 0;
}