_tmain
no existe en C ++. main
hace.
_tmain
es una extensión de Microsoft.
main
es, según el estándar C ++, el punto de entrada del programa. Tiene una de estas dos firmas:
int main();
int main(int argc, char* argv[]);
Microsoft ha agregado un wmain que reemplaza la segunda firma con esto:
int wmain(int argc, wchar_t* argv[]);
Y luego, para facilitar el cambio entre Unicode (UTF-16) y su conjunto de caracteres multibyte, han definido _tmain
qué, si Unicode está habilitado, se compila como wmain
, y de lo contrario como main
.
En cuanto a la segunda parte de su pregunta, la primera parte del rompecabezas es que su función principal es incorrecta. wmain
debería tomar una wchar_t
discusión, no char
. Como el compilador no aplica esto para la main
función, obtienes un programa en el que wchar_t
se pasan una serie de cadenas a la main
función, que las interpreta como char
cadenas.
Ahora, en UTF-16, el juego de caracteres utilizado por Windows cuando Unicode está habilitado, todos los caracteres ASCII se representan como el par de bytes \0
seguido del valor ASCII.
Y dado que la CPU x86 es little-endian, el orden de estos bytes se intercambia, de modo que el valor ASCII viene primero, luego seguido de un byte nulo.
Y en una cadena de caracteres, ¿cómo se termina generalmente la cadena? Sí, por un byte nulo. Por lo tanto, su programa ve un montón de cadenas, cada una de ellas en bytes.
En general, tiene tres opciones al hacer la programación de Windows:
- Utilice explícitamente Unicode (llame a wmain, y para cada función de API de Windows que tome argumentos relacionados con caracteres, llame a la
-W
versión de la función. En lugar de CreateWindow, llame a CreateWindowW). Y en lugar de usar el char
uso wchar_t
, etc.
- Desactiva explícitamente Unicode. Llame a main y CreateWindowA, y use
char
para cadenas.
- Permitir ambos. (llame a _tmain y CreateWindow, que resuelven a main / _tmain y CreateWindowA / CreateWindowW), y usan TCHAR en lugar de char / wchar_t.
Lo mismo se aplica a los tipos de cadena definidos por windows.h: LPCTSTR se resuelve en LPCSTR o LPCWSTR, y para cualquier otro tipo que incluya char o wchar_t, siempre existe una versión -T- que puede utilizarse en su lugar.
Tenga en cuenta que todo esto es específico de Microsoft. TCHAR no es un tipo estándar de C ++, es una macro definida en windows.h. wmain y _tmain también están definidos solo por Microsoft.
UNICODE
. Y algunos otros ajustes para C ++, etc., antes de incluir<windows.h>
. Luego use las funciones Unicode comoCreateWindow
(en general, sinW
necesidad al final)._tmain es una macro que se redefine dependiendo de si compila o no con Unicode o ASCII. Es una extensión de Microsoft y no se garantiza que funcione en ningún otro compilador.
La declaración correcta es
Si se define la macro UNICODE, eso se expande a
De lo contrario se expande a
Su definición va para un poco de cada uno y (si tiene un UNICODE definido) se expandirá a
lo cual es simplemente incorrecto.
std :: cout funciona con caracteres ASCII. Necesita std :: wcout si está utilizando caracteres anchos.
prueba algo como esto
O simplemente puede decidir de antemano si usará caracteres anchos o estrechos. :-)
Actualizado 12 de noviembre de 2013:
Cambió el tradicional "TCHAR" a "_TCHAR", que parece ser la última moda. Ambos funcionan bien.
Fin de actualización
fuente
la convención _T se usa para indicar que el programa debe usar el juego de caracteres definido para la aplicación (Unicode, ASCII, MBCS, etc.). Puede rodear sus cadenas con _T () para que se almacenen en el formato correcto.
fuente
char
s antes. Si su aplicación usa directamente,wchar_t
entonces su aplicación es unicode.Ok, la pregunta parece haber sido respondida bastante bien, la sobrecarga de UNICODE debería tomar una amplia matriz de caracteres como su segundo parámetro. Entonces, si el parámetro de la línea de comando es
"Hello"
que probablemente terminaría como"H\0e\0l\0l\0o\0\0\0"
y su programa solo imprimiría el'H'
antes de que vea lo que cree que es un terminador nulo.Así que ahora te preguntarás por qué incluso compila y enlaza.
Bueno, se compila porque se le permite definir una sobrecarga en una función.
La vinculación es un problema un poco más complejo. En C, no hay información de símbolos decorados, por lo que solo encuentra una función llamada main. Probablemente, argc y argv siempre están ahí como parámetros de la pila de llamadas, en caso de que incluso si su función se define con esa firma, incluso si su función los ignora.
A pesar de que C ++ tiene símbolos decorados, casi con certeza utiliza el enlace C para main, en lugar de un enlazador inteligente que busca cada uno a su vez. Entonces encontró su wmain y puso los parámetros en la pila de llamadas en caso de que sea la
int wmain(int, wchar_t*[])
versión.fuente
Con un poco de esfuerzo para generar esto, funcionaría con cualquier lista de objetos.
fuente