_tmain
tidak ada di C ++. main
tidak.
_tmain
adalah ekstensi Microsoft.
main
adalah, menurut standar C ++, titik masuk program. Ia memiliki salah satu dari dua tanda tangan ini:
int main();
int main(int argc, char* argv[]);
Microsoft telah menambahkan peringatan yang menggantikan tanda tangan kedua dengan ini:
int wmain(int argc, wchar_t* argv[]);
Dan kemudian, untuk membuatnya lebih mudah untuk beralih antara Unicode (UTF-16) dan set karakter multibyte mereka, mereka telah menentukan _tmain
, jika Unicode diaktifkan, dikompilasi sebagai wmain
, dan sebaliknya sebagaimain
.
Adapun bagian kedua dari pertanyaan Anda, bagian pertama dari teka-teki adalah bahwa fungsi utama Anda salah. wmain
harus mengambil wchar_t
argumen, bukan char
. Karena kompiler tidak menjalankan ini untuk main
fungsi, Anda mendapatkan program di mana array wchar_t
string diteruskan ke main
fungsi, yang menafsirkannya sebagai char
string.
Sekarang, di UTF-16, set karakter yang digunakan oleh Windows ketika Unicode diaktifkan, semua karakter ASCII diwakili sebagai pasangan byte \0
diikuti oleh nilai ASCII.
Dan karena CPU x86 adalah little-endian, urutan byte ini ditukar, sehingga nilai ASCII datang terlebih dahulu, kemudian diikuti oleh byte nol.
Dan dalam string char, bagaimana string biasanya diakhiri? Yap, dengan byte nol. Jadi program Anda melihat banyak string, masing-masing panjangnya satu byte.
Secara umum, Anda memiliki tiga opsi saat melakukan pemrograman Windows:
- Secara eksplisit menggunakan Unicode (panggil wmain, dan untuk setiap fungsi Windows API yang mengambil argumen terkait char, panggil
-W
versi fungsi. Alih-alih CreateWindow, panggil CreateWindowW). Dan alih-alih menggunakan char
gunakan wchar_t
, dan sebagainya
- Nonaktifkan Unicode secara eksplisit. Panggil main, dan CreateWindowA, dan gunakan
char
untuk string.
- Izinkan keduanya. (panggil _tmain, dan CreateWindow, yang memutuskan untuk main / _tmain dan CreateWindowA / CreateWindowW), dan gunakan TCHAR sebagai ganti char / wchar_t.
Hal yang sama berlaku untuk tipe string yang didefinisikan oleh windows.h: LPCTSTR memutuskan untuk LPCSTR atau LPCWSTR, dan untuk setiap tipe lain yang menyertakan char atau wchar_t, versi -T- selalu ada yang dapat digunakan sebagai gantinya.
Perhatikan bahwa semua ini khusus untuk Microsoft. TCHAR bukan tipe C ++ standar, ini adalah makro yang didefinisikan di windows.h. wmain dan _tmain juga hanya ditentukan oleh Microsoft.
UNICODE
. Dan beberapa penyesuaian lain untuk C ++ dll, sebelum termasuk<windows.h>
. Kemudian gunakan fungsi Unicode sepertiCreateWindow
(secara umum tanpaW
diperlukan di akhir)._tmain adalah makro yang didefinisikan ulang tergantung pada apakah Anda mengkompilasi dengan Unicode atau ASCII. Ini adalah ekstensi Microsoft dan tidak dijamin untuk bekerja pada kompiler lain.
Deklarasi yang benar adalah
Jika UNICODE makro didefinisikan, yang diperluas menjadi
Kalau tidak, itu akan berkembang
Definisi Anda berlaku untuk masing-masing, dan (jika Anda memiliki UNICODE didefinisikan) akan diperluas ke
yang jelas salah.
std :: cout bekerja dengan karakter ASCII. Anda perlu std :: wcout jika Anda menggunakan karakter lebar.
coba sesuatu seperti ini
Atau Anda bisa saja memutuskan terlebih dahulu apakah akan menggunakan karakter lebar atau sempit. :-)
Diperbarui 12 Nov 2013:
Mengubah "TCHAR" tradisional menjadi "_TCHAR" yang tampaknya menjadi mode terbaru. Keduanya bekerja dengan baik.
Akhiri Pembaruan
sumber
konvensi _T digunakan untuk menunjukkan program harus menggunakan set karakter yang ditentukan untuk aplikasi (Unicode, ASCII, MBCS, dll.). Anda dapat mengelilingi string Anda dengan _T () agar disimpan dalam format yang benar.
sumber
char
s sebelumnya. Jika aplikasi Anda langsung digunakanwchar_t
maka aplikasi Anda adalah unicode.Ok, pertanyaannya tampaknya telah dijawab dengan cukup baik, UNICODE yang berlebihan harus mengambil array karakter yang lebar sebagai parameter kedua. Jadi jika parameter baris perintah
"Hello"
yang mungkin berakhir"H\0e\0l\0l\0o\0\0\0"
dan program Anda hanya akan mencetak'H'
sebelum ia melihat apa yang dianggapnya adalah terminator nol.Jadi sekarang Anda mungkin bertanya-tanya mengapa itu mengkompilasi dan tautan.
Yah itu dikompilasi karena Anda diizinkan untuk mendefinisikan kelebihan fungsi.
Menautkan adalah masalah yang sedikit lebih kompleks. Di C, tidak ada informasi simbol yang didekorasi sehingga hanya menemukan fungsi yang disebut main. Argc dan argv mungkin selalu ada sebagai parameter call-stack untuk berjaga-jaga bahkan jika fungsi Anda didefinisikan dengan tanda tangan itu, bahkan jika fungsi Anda kebetulan mengabaikannya.
Meskipun C ++ memang memiliki simbol yang didekorasi, hampir pasti menggunakan C-linkage untuk main, daripada linker yang pintar yang mencari masing-masing simbol secara bergantian. Jadi ia menemukan wmain Anda dan meletakkan parameter ke tumpukan panggilan jika itu adalah
int wmain(int, wchar_t*[])
versi.sumber
Dengan sedikit upaya templatizing ini, ia akan bekerja dengan daftar objek.
sumber