_tmain
n'existe pas en C ++. main
Est-ce que.
_tmain
est une extension Microsoft.
main
est, selon la norme C ++, le point d'entrée du programme. Il possède l'une de ces deux signatures:
int main();
int main(int argc, char* argv[]);
Microsoft a ajouté un wmain qui remplace la deuxième signature par ceci:
int wmain(int argc, wchar_t* argv[]);
Et puis, pour faciliter le basculement entre Unicode (UTF-16) et leur jeu de caractères multi-octets, ils ont défini _tmain
lequel, si Unicode est activé, est compilé en tant que wmain
, et sinon en tant que main
.
Quant à la deuxième partie de votre question, la première partie du puzzle est que votre fonction principale est incorrecte. wmain
devrait prendre un wchar_t
argument, non char
. Comme le compilateur n'applique pas cela pour la main
fonction, vous obtenez un programme où un tableau de wchar_t
chaînes est passé à la main
fonction, qui les interprète comme des char
chaînes.
Maintenant, en UTF-16, le jeu de caractères utilisé par Windows lorsque Unicode est activé, tous les caractères ASCII sont représentés comme la paire d'octets \0
suivie de la valeur ASCII.
Et comme le processeur x86 est peu endian, l'ordre de ces octets est inversé, de sorte que la valeur ASCII vient en premier, puis est suivie d'un octet nul.
Et dans une chaîne de caractères, comment la chaîne se termine-t-elle généralement? Oui, par un octet nul. Votre programme voit donc un tas de chaînes, chacune d'un octet de long.
En général, vous avez trois options lors de la programmation Windows:
- Utilisez explicitement Unicode (appelez wmain, et pour chaque fonction API Windows qui prend des arguments liés aux caractères, appelez la
-W
version de la fonction. Au lieu de CreateWindow, appelez CreateWindowW). Et au lieu d'utiliser l' char
utilisation wchar_t
, etc.
- Désactivez explicitement Unicode. Appelez main et CreateWindowA et utilisez
char
pour les chaînes.
- Autorisez les deux. (appelez _tmain et CreateWindow, qui se résolvent en main / _tmain et CreateWindowA / CreateWindowW), et utilisez TCHAR au lieu de char / wchar_t.
La même chose s'applique aux types de chaîne définis par windows.h: LPCTSTR se résout en LPCSTR ou LPCWSTR, et pour tout autre type qui inclut char ou wchar_t, une version -T- existe toujours qui peut être utilisée à la place.
Notez que tout cela est spécifique à Microsoft. TCHAR n'est pas un type C ++ standard, c'est une macro définie dans windows.h. wmain et _tmain sont également définis par Microsoft uniquement.
UNICODE
. Et quelques autres ajustements pour C ++ etc., avant d'inclure<windows.h>
. Utilisez ensuite les fonctions Unicode commeCreateWindow
(en général sansW
besoin à la fin)._tmain est une macro qui est redéfinie selon que vous compilez avec Unicode ou ASCII. Il s'agit d'une extension Microsoft et il n'est pas garanti de fonctionner sur d'autres compilateurs.
La bonne déclaration est
Si la macro UNICODE est définie, elle se développe en
Sinon, il se développe pour
Votre définition va pour un peu de chacun, et (si vous avez défini UNICODE) s'étendra à
ce qui est tout simplement faux.
std :: cout fonctionne avec des caractères ASCII. Vous avez besoin de std :: wcout si vous utilisez des caractères larges.
essayez quelque chose comme ça
Ou vous pouvez simplement décider à l'avance d'utiliser des caractères larges ou étroits. :-)
Mis à jour le 12 nov.2013:
Changé le traditionnel "TCHAR" en "_TCHAR" qui semble être la dernière mode. Les deux fonctionnent bien.
Mettre à jour la fin
la source
la convention _T est utilisée pour indiquer que le programme doit utiliser le jeu de caractères défini pour l'application (Unicode, ASCII, MBCS, etc.). Vous pouvez entourer vos chaînes avec _T () pour les stocker dans le format correct.
la source
char
s auparavant. Si votre application utilise directement,wchar_t
votre application est unicode.Ok, la question semble avoir été assez bien répondu, la surcharge UNICODE devrait prendre un large tableau de caractères comme deuxième paramètre. Donc, si le paramètre de ligne de commande est,
"Hello"
cela finirait probablement par"H\0e\0l\0l\0o\0\0\0"
et votre programme afficherait uniquement le'H'
avant de voir ce qu'il pense être un terminateur nul.Alors maintenant, vous vous demandez peut-être pourquoi il compile et établit des liens.
Eh bien, il compile parce que vous êtes autorisé à définir une surcharge pour une fonction.
La liaison est un problème légèrement plus complexe. En C, il n'y a aucune information de symbole décoré, donc il trouve juste une fonction appelée main. L'argc et l'argv sont probablement toujours là en tant que paramètres de pile d'appels au cas où même si votre fonction est définie avec cette signature, même si votre fonction les ignore.
Même si C ++ possède des symboles décorés, il utilise presque certainement C-linkage pour main, plutôt qu'un éditeur de liens intelligent qui les recherche tour à tour. Il a donc trouvé votre wmain et mis les paramètres sur la pile d'appels au cas où ce serait la
int wmain(int, wchar_t*[])
version.la source
Avec un petit effort de création de modèles, cela fonctionnera avec n'importe quelle liste d'objets.
la source