_tmain
не существует в C ++. main
делает.
_tmain
это расширение Microsoft.
main
является, согласно стандарту C ++, точкой входа в программу. Он имеет одну из этих двух подписей:
int main();
int main(int argc, char* argv[]);
Microsoft добавила wmain, который заменяет вторую подпись следующим образом:
int wmain(int argc, wchar_t* argv[]);
И затем, чтобы облегчить переключение между Unicode (UTF-16) и их многобайтовым набором символов, они определили, _tmain
который, если Unicode включен, компилируется как wmain
, а в противном случае как main
.
Что касается второй части вашего вопроса, первая часть головоломки состоит в том, что ваша основная функция неверна. wmain
следует принять wchar_t
аргумент, а не char
. Поскольку компилятор не предписывает это для main
функции, вы получаете программу, в которую массив wchar_t
строк передается main
функции, которая интерпретирует их как char
строки.
Теперь в UTF-16, наборе символов, используемом Windows, когда включен Unicode, все символы ASCII представлены в виде пары байтов, \0
за которыми следует значение ASCII.
А поскольку процессор x86 имеет младший порядок, порядок этих байтов меняется, так что сначала идет значение ASCII, а затем нулевой байт.
И в строке char, как обычно завершается строка? Да, нулевым байтом. Итак, ваша программа видит кучу строк, каждая длиной в один байт.
В общем, у вас есть три варианта программирования Windows:
- Явно используйте Unicode (вызовите wmain, и для каждой функции Windows API, которая принимает аргументы, связанные с символами, вызовите
-W
версию функции. Вместо CreateWindow, вызовите CreateWindowW). И вместо использования char
использовать wchar_t
, и так далее
- Явно отключить Юникод. Вызовите main, CreateWindowA и используйте
char
для строк.
- Разрешить оба. (вызовите _tmain и CreateWindow, которые разрешают main / _tmain и CreateWindowA / CreateWindowW), и используйте TCHAR вместо char / wchar_t.
То же самое относится к строковым типам, определенным в windows.h: LPCTSTR разрешается либо в LPCSTR, либо в LPCWSTR, а для каждого другого типа, который включает char или wchar_t, всегда существует -T-версия, которую можно использовать вместо этого.
Обратите внимание, что все это специфично для Microsoft. TCHAR не является стандартным типом C ++, это макрос, определенный в windows.h. wmain и _tmain также определяются только Microsoft.
UNICODE
. И некоторые другие настройки для C ++ и т. Д., Прежде чем включать<windows.h>
. Затем используйте такие функции Unicode, какCreateWindow
(обычно безW
необходимости в конце)._tmain - это макрос, который переопределяется в зависимости от того, используете ли вы Unicode или ASCII или нет. Это расширение от Microsoft и не гарантированно работает на любых других компиляторах.
Правильная декларация
Если определен макрос UNICODE, он расширяется до
В противном случае он расширяется до
Ваше определение относится к понятию каждого и (если у вас определен UNICODE) расширится до
что просто неправильно.
std :: cout работает с символами ASCII. Вам нужен std :: wcout, если вы используете широкие символы.
попробуй что-нибудь подобное
Или вы можете просто решить заранее, использовать ли широкие или узкие символы. :-)
Обновлено 12 ноября 2013 года:
Изменил традиционную "TCHAR" на "_TCHAR", что, похоже, является последней модой. Оба работают нормально.
Конец обновления
источник
Соглашение _T используется, чтобы указать, что программа должна использовать набор символов, определенный для приложения (Unicode, ASCII, MBCS и т. д.). Вы можете окружить свои строки с помощью _T (), чтобы сохранить их в правильном формате.
источник
char
s раньше. Если ваше приложение использует напрямую,wchar_t
то ваше приложение является Unicode.Хорошо, вопрос, кажется, был получен достаточно хорошо, перегрузка UNICODE должна принимать массив широких символов в качестве второго параметра. Таким образом, если параметр командной строки будет таким,
"Hello"
что, вероятно, в итоге будет,"H\0e\0l\0l\0o\0\0\0"
и ваша программа будет печатать только'H'
до того, как она увидит то, что она считает нулевым терминатором.Так что теперь вы можете задаться вопросом, почему он даже компилирует ссылки.
Ну, это компилируется, потому что вы можете определить перегрузку для функции.
Связывание - это немного более сложная проблема. В C нет информации о декорированных символах, поэтому он просто находит функцию с именем main. Argc и argv, вероятно, всегда присутствуют в качестве параметров стека вызовов на всякий случай, даже если ваша функция определена с этой сигнатурой, даже если ваша функция игнорирует их.
Несмотря на то, что C ++ действительно имеет декорированные символы, он почти наверняка использует C-linkage для main, а не для умного компоновщика, который ищет каждый из них по очереди. Таким образом, он нашел ваш wmain и поместил параметры в стек вызовов на случай, если это
int wmain(int, wchar_t*[])
версия.источник
Приложив немного усилий для его настройки, он сможет работать с любым списком объектов.
источник