Para ver el artículo en inglés, active la casilla Inglés. También puede ver el texto en inglés en una ventana emergente si pasa el puntero del mouse por el texto.
Traducción
Inglés

ATL and MFC String Conversion Macros

 

Las macros de conversión de cadena en las que se centra este tema son válidas tanto para ATL como para MFC.Para más información sobre la conversión de cadenas de MFC, vea el tema TN059 sobre el uso de macros de conversión de MBCS/Unicode de MFC y el tema sobre globales y macros de MFC.

ATL 7.0 incluye varias macros y clases de conversión nuevas que suponen una notable mejora con respecto a las macros anteriores.

Los nombres de estas nuevas macros y clases de conversión de cadena tienen el siguiente formato:

C SourceType 2[C]DestinationType[EX]

donde:

  • SourceType y DestinationType se describen en la tabla de abajo.

  • [C] está presente cuando el tipo de destino debe ser constante.

  • [EX] está presente cuando el tamaño inicial del búfer se debe especificar como un argumento de plantilla.

    SourceType/DestinationType

    Descripción

    a

    Cadena de caracteres ANSI.

    W

    Cadena de caracteres Unicode.

    T

    Cadena de caracteres genéricos (equivale a W cuando se define _UNICODE y, si no, a A).

    OLE

    Cadena de caracteres OLE (equivale a W).

Por ejemplo, para convertir una cadena Unicode a una cadena genérica sin modificar la cadena convertida, use CW2CT.

System_CAPS_warningAdvertencia

Algunas de las permutaciones de patrón arriba mencionadas no se admiten. CA2CW y CW2CA (y CA2CWEX y CW2CAEX) no se admiten.En el caso de las conversiones de cadenas de caracteres OLE, solo se admite COLE2T y CT2OLE (y COLE2CT, COLE2TEX, COLE2CTEX, CT2COLE, CT2OLEEX y CT2COLEEX).Para conocer más detalles, vea atlconv.h.

Si tiene la certeza de que la cadena convertida no va a superar los 64 caracteres, puede usar la versión EX (como CW2CTEX<64>) para ahorrar espacio en la pila.

System_CAPS_noteNota

El método recomendado para convertir a y desde cadenas BSTR consiste en usar la clase CComBSTR.Para convertir a una cadena BSTR, pase la cadena existente al constructor de CComBSTR.Para convertir desde una cadena BSTR, use COLE2[C]DestinationType[EX], como COLE2T.

Las nuevas clases de conversión que requieren un búfer (CA2AEX, CA2WEX, CW2AEX y CW2WEX) usan un búfer estático de tamaño fijo para almacenar el resultado de la conversión.Si el resultado es demasiado grande y no encaja en el búfer estático, la clase asigna memoria por medio de malloc, memoria que libera cuando el objeto se sale del ámbito.De este modo, estas clases se pueden usar con total seguridad en bucles y no desbordarán la pila, al contrario de lo que sucede con las antiguas macros de conversión de texto.

Las macros de conversión incluidas en ATL 7.0 se han optimizado para que reconozcan cadenas NULL de entrada.Así, estas macros devolverán NULL si el parámetro de entrada es NULL sin asignar nada de memoria.

Las macros y clases de conversión de ATL utilizarán de forma predeterminada la página de código ANSI del subproceso actual para la conversión.Si desea invalidar este comportamiento en una conversión concreta donde se usan macros basadas en las clases CA2WEX o CW2AEX, indique la página de código como segundo parámetro del constructor de la clase.

System_CAPS_security Seguridad Nota

Compruebe la longitud de las cadenas antes de pasarlas a estas macros para evitar posibles problemas de saturación de búfer.Los desbordamientos de pila son excepciones que también se podrían interceptar mediante try/except.

Existen algunas diferencias importantes entre las macros de conversión de cadena antiguas y las nuevas:

Macros de conversión de cadena de ATL 3.0 antiguas

Macros de conversión de cadena de ATL 7.0 nuevas

Asigna memoria en la pila.

Usan memoria de la pila en las cadenas pequeñas.Usan el montón si la pila no es lo suficientemente grande.

La cadena se libera cuando la función se cierra.

La cadena se libera cuando la variable se sale del ámbito.

No se pueden usar en controladores de excepción.

Se pueden usar en controladores de excepción.

Su uso no es apto en bucles.El uso de memoria va en aumento hasta que la función se cierra.

Admiten el uso en bucles.El ámbito de bucle garantiza que se libera memoria en cada iteración.

No son adecuadas en cadenas de gran tamaño.El espacio de pila es limitado.

No presentan problemas con las cadenas de gran tamaño.Las cadenas se asignarán en el montón.

Suelen requerir que USES_CONVERSION se haya definido.

No requieren nunca que USES_CONVERSION se haya definido.

El significado de OLE depende de la definición de OLE2ANSI.

OLE siempre equivale a W.

//Example 1
// Convert LPCWSTR to LPCSTR.
void ExampleFunction1(LPCWSTR pszW)
{
   // Create an instance of CW2A, called pszA,
   // and initialize it with pszW.
   CW2A pszA(pszW);
   // pszA works like an LPCSTR, and can be used thus:
   ExampleFunctionA(pszA);  
   // Note: pszA will become invalid when it goes out of scope.
}

// Example 2
// Use a temporary instance of CW2A.
void ExampleFunction2(LPCWSTR pszW)
{
   // Create a temporary instance of CW2A,
   // and initialize it with pszW.
   ExampleFunctionA(CW2A(pszW));
   // Note: the temporary instance becomes invalid 
   // after the execution of the statement above.
}

// Example 3
// Incorrect use of conversion macros.
void ExampleFunction3(LPCWSTR pszW)
{
   // Create a temporary instance of CW2A,
   // save a pointer to it and then delete
   // the temportary instance.
   LPCSTR pszA = CW2A(pszW);
   // The pszA in the following line is an invalid pointer,
   // as the instance of CW2A has gone out of scope.
   ExampleFunctionA(pszA);
}

Es necesario hacer hincapié en que el siguiente código no es adecuado:

LPCTSTR szr = CA2T(szReplaceFile);

Con las macros de ATL 3.0, se podía usar esto:

LPCTSTR szr = A2T(szReplaceFile);   

dado que la memoria asignada por las funciones de conversión no se liberaría hasta que la función actual se cerrara.Este mismo código no funciona con las clases nuevas.

Este código:

LPCTSTR szr = CA2T(szReplaceFile);   

equivale a esto:

LPCTSTR szr;
{
   CA2T temp(szReplaceFile);
   szr = temp.operator LPTSTR();
}   

El uso del valor en szr tendría resultados no deseados, ya que la memoria asignada por el objeto temporal y procedente del operador de conversión se destruye cuando lo hace el objeto temporal.

Use este código en su lugar:

CA2T szr(szReplaceFile);   

El operador de conversión hace que el objeto CA2T parezca un LPCTSTR.

El tamaño predeterminado del búfer estático es de 128 caracteres.En caso de que sea necesario modificar el tamaño del búfer en una conversión específica, use la versión EX de una macro e indique el tamaño de búfer como un argumento de plantilla.

// Example 4
// Changing the size of the buffer.
void ExampleFunction4(LPCWSTR pszW)
{
   // Use a 16-character buffer.
   ExampleFunctionA(CW2AEX<16>(pszW));
}

Este es un ejemplo de cómo se especifica la página de código como segundo parámetro al constructor de la clase.

// Example 5
// Specifying the code page.
void ExampleFunction5(LPCWSTR pszW)
{
   // Convert to the Macintosh code page
   ExampleFunctionA(CW2A(pszW, CP_MACCP));
}

Las macros de conversión de texto originales siguen estando disponibles. Las hemos recogido en la siguiente tabla:

Macros de conversión de cadena de ATL 3.0

A2BSTR

OLE2A

T2A

W2A

A2COLE

OLE2BSTR

T2BSTR

W2BSTR

A2CT

OLE2CA

T2CA (Desusada.Use T2CA_EX o CT2CA en su lugar).

W2CA

A2CW

OLE2CT

T2COLE

W2COLE

A2OLE

OLE2CW

T2CW

W2CT

A2T

OLE2T

T2OLE

W2OLE

A2W

OLE2W

T2W

W2T

La sintaxis para usar estas macros es la siguiente:

MACRONAME( string_address )

Por ejemplo:

A2W(lpa);

En los nombres de macro, el tipo de cadena de origen aparece a la izquierda (por ejemplo, A) y el tipo de cadena de destino, a la derecha (por ejemplo, W). A corresponde a LPSTR, OLE a LPOLESTR, T a LPTSTR y W a LPWSTR.

Si hay una C en el nombre de macro, la macro realiza una conversión a una cadena const.Por ejemplo, W2CA convierte un LPWSTR en un LPCSTR.

En consecuencia, A2W convierte un LPSTR en un LPWSTR, OLE2T convierte un LPOLESTR en un LPTSTR, y así sucesivamente.

El comportamiento de las macros de conversión de cadena de ATL depende de la directiva de compilador que haya en vigor (si la hay).Si los tipos de origen y de destino son el mismo, no tiene lugar ninguna conversión.Las directivas de compilador cambian T y OLE del siguiente modo:

Directiva de compilador vigente

T pasa a

OLE pasa a

NONE

a

W

_UNICODE

W

W

OLE2ANSI

a

a

_UNICODE y OLE2ANSI

W

a

La cadena de destino se crea mediante _alloca, salvo cuando el tipo de destino es BSTR.Si se usa _alloca, se asigna memoria de la pila, con lo cual, cuando la función regresa, se limpia automáticamente.Esta macro solo convertirá un máximo de 500 KB de forma predeterminada cada vez.

Cuando use una macro de conversión de cadena de ATL, especifique la macro USES_CONVERSION al inicio de la función para evitar que se produzcan errores de compilador.Por ejemplo:

void StringFunc(LPSTR lpsz)
{
   USES_CONVERSION;

   LPWSTR x = A2W(lpsz);
   // Do something with x
   wprintf_s(L"x is %s", x);
}

Archivo de encabezado: AtlBase.h, AtlConv.h (declarado en AtlConv.h)

Mostrar: