Para quienes inician en el desarrollo en C++/Win32 o quienes desarrollan en C#/PInvoke pronto  descubriran que Windows tiene varias definiciones para el tipo de dato char (C++) o string (C#). Las multiples definiones obedecen (desde mi punto de visto) al buen proposito de mantener el codigo generico en cuanto al soporte o no de caracteres Unicode.

Es tan comun la confusion de estos tipos de datos que una macro facil de consumir como por ejemplo MCIWndSave causa comentarios en los foros como “MCIWndSave is not saving ok the filename” debido a que se utiliza incorrectamente como lo muestra el siguiente codigo:

char file[96]="";
strcpy(file,"aud.wav");
MCIWndSave(m_hMCIWnd, file);

Existen otros malos ejemplos con llamados ANSI. Para ayudar a eliminar las dudas entre las definiciones de las cadenas en Windows decidi elaborar la siguiente tabla para resumirlos:

ANSI UNICODE
TCHAR char WCHAR, wchar_t
PTSTR/LPTSTR PSTR: char* PWSTR: WCHAR*
LPSTR: char* LPWSTR: WCHAR*
PTCHAR: TCHAR* PCHAR: char* PWCHAR: WCHAR*
PCTSTR/LPCTSTR PCSTR: const char* PCWSTR: WCHAR*
LPCSTR: const char* LPCWSTR: const WCHAR*

De los anteriores tipos tal vez solo identifiques al char. Pues bien la clasificacion divide en el grupo que soporta caracteres Unicode (2 bytes) y en el grupo que solo soporta caracteres ANSI (1 byte). El char es de tipo ANSI, por lo cual podras representar todos los caracteres del idioma ingles con facilidad pero no para representar otra escritura como el texto Cyrilic. Asi mismo la version Unicode del char es el WCHAR.

Basado en el char (ANSI) y el WCHAR (Unicode) encontramos los punteros/apuntadores/pointers a ellos, los cuales pueden ser variables o constantes. En el caso de los char* se definen como PSTR (Pointer to STRing) o LPTSTR (Long Pointer to STRing). Auque se definan Long Pointer la verdadera diferencia la crea el desarrollador porque la definicion segun la macro  es la misma. Los const char* pueden ser PCSTR (Pointer to Constant String) o LPCSTR (Long Pointer To Constant String).

Los WCHAR* y const WCHAR* siguen la misma filosofia de los char* y const char*, es decir existe dos definiones para los varibales (PWSTR y LPWSTR) y dos para los constantes (PCWSTR y LPCWSTR). Adicionalmente existe el TCHAR que dependiendo si existe o no el #define Unicode se convierte en char o WCHAR. Un par de ejemplos de cadenas ANSI y Unicode:

char* unaCadena="una cadena";
WCHAR* unaCadena=L"una cadena";
TCHAR* unaCadena= _T("una cadena");

Del mismo modo existen versiones de todas las funciones para cada definicion, por ejemplo:

strlen(unaCadena);
wcslen(unaCadena);
_tcslen(unaCadena);

Si quieres aprender mas puedes visitar la documentacion en MSDN o este articulo en CodeProject.

Cheers,

Javier Andrés Cáceres Alvis

Microsoft Most Valuable Professional – MVP
Intel Black Belt Software Developer