Conversión de System::String a Char en Visual C++

En este artículo se describen varias maneras de convertir de System::String* a char* mediante extensiones administradas en Visual C++.

Versión original del producto: Visual C++
Número de KB original: 311259

Resumen

En este artículo se hace referencia a los siguientes espacios de nombres de la biblioteca de clases de Microsoft .NET Framework:

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

En este artículo se describen varias maneras de convertir de System::String* a char* mediante lo siguiente:

  • Extensiones administradas para C++ en Visual C++ .NET 2002 y en Visual C++ .NET 2003
  • C++/CLI en Visual C++ 2005 y en Visual C++ 2008

Método 1

PtrToStringChars proporciona un puntero interior al objeto real String . Si pasa este puntero a una llamada de función no administrada, primero debe anclar el puntero para asegurarse de que el objeto no se mueve durante un proceso asincrónico de recolección de elementos no utilizados:

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

Método 2

StringToHGlobalAnsi copia el contenido de un objeto administrado String en un montón nativo y, a continuación, lo convierte en el formato de American National Standards Institute (ANSI) sobre la marcha. Este método asigna la memoria de montón nativa necesaria:

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

Nota:

En Visual C++ 2005 y en Visual C++ 2008, debe agregar la opción del compilador de compatibilidad con Common Language Runtime (/clr:oldSyntax) para compilar correctamente el ejemplo de código anterior. Para agregar la opción del compilador de compatibilidad con Common Language Runtime, siga estos pasos:

  1. Haga clic en Proyectoy, a continuación, haga clic en Propiedades de NombreDeProyecto.

    Nota:

    ProjectName es un marcador de posición para el nombre del proyecto.

  2. Expanda Propiedades de configuracióny, a continuación, haga clic en General.

  3. En el panel derecho, haga clic para seleccionar Compatibilidad con Common Language Runtime, Sintaxis antigua (/clr:oldSyntax) en la configuración del proyecto de soporte técnico de Common Language Runtime .

  4. En el cuadro Plan de marcado (contexto telefónico), haga clic en Examinar para buscar el plan de marcado del usuario.

Para obtener más información sobre las opciones del compilador de compatibilidad con Common Language Runtime, visite el siguiente sitio web de Microsoft Developer Network (MSDN):

/clr (compilación de Common Language Runtime)

Estos pasos se aplican a todo el artículo.

Método 3

La clase VC7 CString tiene un constructor que toma un puntero String administrado y carga con CString su contenido:

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

Método 4

Visual C++ 2008 presenta la marshal_as<T> clase de ayuda marshal y la marshal_context() clase auxiliar marshal.

//#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;

Nota:

Este código no se compila mediante extensiones administradas para C++ en Visual C++ .NET 2002 o en Visual C++ .NET 2003. Usa la nueva sintaxis de C++/CLI que se introdujo en Visual C++ 2005 y el nuevo código de espacio de nombres msclr que se introdujo en Visaul C++ 2008. Para compilar correctamente este código, debe usar el modificador del compilador de C++ /clr en Visual C++ 2008.

Extensiones administradas para C++ código de ejemplo (Visual C++ 2002 o 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ódigo de ejemplo de C++/CLI (Visual C++ 2005 y 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;
}