_tmain
não existe em C ++. main
faz.
_tmain
é uma extensão da Microsoft.
main
é, de acordo com o padrão C ++, o ponto de entrada do programa. Ele possui uma dessas duas assinaturas:
int main();
int main(int argc, char* argv[]);
A Microsoft adicionou um wmain que substitui a segunda assinatura por esta:
int wmain(int argc, wchar_t* argv[]);
E, para facilitar a alternância entre o Unicode (UTF-16) e seu conjunto de caracteres multibyte, eles definiram _tmain
qual, se o Unicode estiver ativado, será compilado como wmain
e, caso contrário, como main
.
Quanto à segunda parte da sua pergunta, a primeira parte do quebra-cabeça é que sua função principal está errada. wmain
deve levar uma wchar_t
discussão, não char
. Como o compilador não impõe isso para a main
função, você obtém um programa no qual uma matriz de wchar_t
strings é passada para a main
função, que as interpreta como char
strings.
Agora, no UTF-16, o conjunto de caracteres usado pelo Windows quando o Unicode está ativado, todos os caracteres ASCII são representados como o par de bytes \0
seguido pelo valor ASCII.
E como a CPU x86 é little-endian, a ordem desses bytes é trocada, para que o valor ASCII seja o primeiro e, em seguida, seguido por um byte nulo.
E em uma string de caracteres, como a string geralmente é terminada? Sim, por um byte nulo. Portanto, seu programa vê várias seqüências de caracteres, cada uma com um byte de comprimento.
Em geral, você tem três opções ao executar a programação do Windows:
- Use explicitamente Unicode (chamada wmain e, para cada função da API do Windows que aceite argumentos relacionados a char, chame a
-W
versão da função. Em vez de CreateWindow, chame CreateWindowW). E em vez de usar char
use wchar_t
, e assim por diante
- Desabilite explicitamente o Unicode. Chame main e CreateWindowA e use
char
para strings.
- Permita ambos. (chame _tmain e CreateWindow, que resolve como main / _tmain e CreateWindowA / CreateWindowW) e use TCHAR em vez de char / wchar_t.
O mesmo se aplica aos tipos de sequência definidos por windows.h: LPCTSTR resolve LPCSTR ou LPCWSTR e para todos os outros tipos que incluem char ou wchar_t, sempre existe uma versão -T que pode ser usada.
Observe que tudo isso é específico da Microsoft. TCHAR não é um tipo C ++ padrão, é uma macro definida em windows.h. wmain e _tmain também são definidos apenas pela Microsoft.
UNICODE
. E alguns outros ajustes para C ++ etc., antes de incluir<windows.h>
. Em seguida, use as funções Unicode comoCreateWindow
(em geral, semW
necessidade no final)._tmain é uma macro redefinida, dependendo se você compila ou não com Unicode ou ASCII. É uma extensão da Microsoft e não é garantido que funcione em outros compiladores.
A declaração correta é
Se a macro UNICODE for definida, ela se expande para
Caso contrário, ele se expande para
Sua definição vale um pouco de cada e (se você tiver UNICODE definido) será expandida para
o que é simplesmente errado.
std :: cout trabalha com caracteres ASCII. Você precisa std :: wcout se estiver usando caracteres largos.
tente algo assim
Ou você pode decidir com antecedência se deve usar caracteres largos ou estreitos. :-)
Atualizado 12 de novembro de 2013:
Alterou o tradicional "TCHAR" para "_TCHAR", que parece ser a última moda. Ambos funcionam bem.
Finalizar atualização
fonte
a convenção _T é usada para indicar que o programa deve usar o conjunto de caracteres definido para o aplicativo (Unicode, ASCII, MBCS, etc.). Você pode colocar suas seqüências de caracteres com _T () para armazená-las no formato correto.
fonte
char
s antes. Se seu aplicativo usar diretamente,wchar_t
ele será unicode.Ok, a pergunta parece ter sido respondida razoavelmente bem, a sobrecarga do UNICODE deve ter uma ampla matriz de caracteres como seu segundo parâmetro. Portanto, se o parâmetro da linha de comando for
"Hello"
esse, provavelmente terminará como"H\0e\0l\0l\0o\0\0\0"
e seu programa apenas imprimirá o arquivo'H'
antes de ver o que ele acha que é um terminador nulo.Então agora você pode se perguntar por que ele ainda compila e vincula.
Bem, ele compila porque você pode definir uma sobrecarga para uma função.
A vinculação é uma questão um pouco mais complexa. Em C, não há informações decorativas sobre os símbolos, apenas encontra uma função chamada main. O argc e o argv provavelmente estão sempre lá como parâmetros da pilha de chamadas, mesmo que sua função seja definida com essa assinatura, mesmo que sua função os ignore.
Embora o C ++ tenha símbolos decorados, ele certamente usa o C-linkage para main, em vez de um vinculador inteligente que procura cada um por vez. Por isso, encontrou o seu domínio e colocou os parâmetros na pilha de chamadas, caso seja a
int wmain(int, wchar_t*[])
versão.fonte
Com um pouco de esforço para modelar isso, funcionaria com qualquer lista de objetos.
fonte