Hãy xem xét chương trình cấp API của Windows sau:
#define NOMINMAX
#include <windows.h>
int main()
{
MessageBox( 0, "Blah blah...", "My Windows app!", MB_SETFOREGROUND );
}
Bây giờ chúng ta hãy xây dựng nó bằng cách sử dụng chuỗi công cụ GNU (tức là g ++), không có tùy chọn đặc biệt. Đâygnuc
chỉ là một tệp hàng loạt mà tôi sử dụng cho việc đó. Nó chỉ cung cấp các tùy chọn để làm cho g ++ trở nên chuẩn hơn:
C: \ test> gnuc x.cpp
C: \ test> objdump -x a.exe | findstr / i "^ hệ thống con"
Hệ thống con 00000003 (Windows CUI)
C: \ test> _
Điều này có nghĩa là trình liên kết theo mặc định đã tạo ra một hệ thống con bảng điều khiển có thể thực thi được. Các hệ thống phụ giá trị trong phần đầu tập tin để nói cho Windows những dịch vụ chương trình yêu cầu. Trong trường hợp này, với hệ thống giao diện điều khiển, chương trình yêu cầu một cửa sổ giao diện điều khiển.
Điều này cũng làm cho trình thông dịch lệnh đợi chương trình hoàn thành.
Bây giờ hãy xây dựng nó với hệ thống con GUI , điều này có nghĩa là chương trình không yêu cầu cửa sổ giao diện điều khiển:
C: \ test> gnuc x.cpp -mwindows
C: \ test> objdump -x a.exe | findstr / i "^ hệ thống con"
Hệ thống con 00000002 (Windows GUI)
C: \ test> _
Hy vọng rằng điều đó là ổn cho đến nay, mặc dù -mwindows
lá cờ chỉ là tài liệu bán phần.
Việc xây dựng mà không có cờ bán tài liệu đó, người ta sẽ phải nói cụ thể hơn cho trình liên kết biết giá trị hệ thống con nào mà người ta mong muốn và một số thư viện nhập API Windows nói chung sẽ phải được chỉ định rõ ràng:
C: \ test> gnuc x.cpp -Wl,-subsystem, windows
C: \ test> objdump -x a.exe | findstr / i "^ hệ thống con"
Hệ thống con 00000002 (Windows GUI)
C: \ test> _
Điều đó hoạt động tốt, với chuỗi công cụ GNU.
Nhưng còn chuỗi công cụ Microsoft, tức là Visual C ++ thì sao?
Vâng, xây dựng như một hệ thống con bảng điều khiển có thể thực thi hoạt động tốt:
C: \ test> msvc x.cpp user32.lib
x.cpp
C: \ test> dumpbin / headers x.exe | tìm / i "hệ thống con" | tìm / i "Windows"
3 hệ thống con (Windows CUI)
C: \ test> _
Tuy nhiên, với việc xây dựng chuỗi công cụ của Microsoft dưới dạng hệ thống con GUI không hoạt động theo mặc định:
C: \ test> msvc x.cpp user32.lib / link / subsystem: windows
x.cpp
LIBCMT.lib (wincrt0.obj): lỗi LNK2019: ký hiệu bên ngoài chưa được giải quyết _WinMain @ 16 được tham chiếu trong hàm ___tmainCRTStartu
p
x.exe: lỗi nghiêm trọng LNK1120: 1 bên ngoài chưa được giải quyết
C: \ test> _
Về mặt kỹ thuật, điều này là do trình liên kết của Microsoft không phải là tiêu chuẩn theo mặc định cho hệ thống con GUI . Theo mặc định, khi hệ thống con là GUI, thì trình liên kết của Microsoft sử dụng điểm nhập thư viện thời gian chạy , hàm nơi bắt đầu thực thi mã máy, được gọi winMainCRTStartup
, gọi là không chuẩn của Microsoft WinMain
thay vì chuẩn main
.
Không có vấn đề lớn để sửa chữa điều đó, mặc dù.
Tất cả những gì bạn phải làm là cho trình liên kết của Microsoft biết điểm nhập nào sẽ sử dụng, cụ thể là điểm mainCRTStartup
nào gọi là tiêu chuẩn main
:
C: \ test> msvc x.cpp user32.lib / link / subsystem: windows / entry: mainCRTStartup
x.cpp
C: \ test> dumpbin / headers x.exe | tìm / i "hệ thống con" | tìm / i "Windows"
2 hệ thống con (Windows GUI)
C: \ test> _
Không sao, nhưng rất tẻ nhạt. Và phức tạp và ẩn giấu đến nỗi hầu hết các lập trình viên Windows, những người chủ yếu chỉ sử dụng các công cụ không phải là tiêu chuẩn theo mặc định của Microsoft, thậm chí không biết về nó, và nhầm tưởng rằng một chương trình hệ thống con Windows GUI “phải” có tiêu chuẩn WinMain
thay vì tiêu chuẩn. main
. Nói cách khác, với C ++ 0x, Microsoft sẽ gặp vấn đề với điều này, vì trình biên dịch sau đó phải quảng cáo xem nó đang ở chế độ chờ hay được lưu trữ (khi được lưu trữ, nó phải hỗ trợ tiêu chuẩn main
).
Dù sao, đó là lý do tại sao g ++ có thể phàn nàn về việc WinMain
thiếu: đó là một chức năng khởi động không chuẩn ngớ ngẩn mà các công cụ của Microsoft yêu cầu theo mặc định cho các chương trình hệ thống con GUI.
Nhưng như bạn có thể thấy ở trên, g ++ không có vấn đề gì với tiêu chuẩn main
ngay cả đối với một chương trình hệ thống con GUI.
Vì vậy, những gì có thể là vấn đề?
Chà, có lẽ bạn đang thiếu a main
. Và bạn có thể không có (thích hợp) WinMain
! Và sau đó g ++, sau khi đã tìm kiếm main
(không phải như vậy) và cho không phải tiêu chuẩn của Microsoft WinMain
(không có như vậy), báo cáo rằng cái sau bị thiếu.
Thử nghiệm với một nguồn trống:
C: \ test> gõ nul> y.cpp
C: \ test> gnuc y.cpp -mwindows
c: / program files / mingw / bin /../ lib / gcc / mingw32 / 4.4.1 /../../../ libmingw32.a (main.o): main.c :(. text + 0xd2 ): tham chiếu không xác định
ce thành `WinMain @ 16 '
Collect2: ld trả về 1 trạng thái thoát
C: \ test> _
All you have to do is to tell Microsoft's linker which entry point to use, namely mainCRTStartup, which calls standard main
. Có cách nào để làm điều đóEclipse CDT
vì tôi không sử dụng dòng lệnh. Cảm ơn