2009-12-02 31 views
5

Tôi tự hỏi tại sao WinAPI lại khác nhiều so với lập trình C bình thường? Tôi có nghĩa là, ở trường tôi đã học được rằng mỗi chương trình C có một hàm main() (WinAPI sử dụng WinMain với một số tham số đặc biệt), một số kiểu biến như int, long, char, vv .. (WinAPI sử dụng những thứ như LPCSTR, BOOL , v.v.) tại sao Microsoft quyết định đi theo một cách khác với API OS của họ?Tại sao WinAPI lại khác với C "bình thường"?

Khi tôi thấy chương trình WinAPI đầu tiên của tôi, tôi có vẻ giống như một ngôn ngữ mới đối với tôi ...;)

+1

Inno - Tôi không chắc tại sao MS sử dụng #defines cho nhiều loại biến của chúng. Nếu bạn muốn biết tại sao họ quyết định làm điều đó, tôi sẽ gửi email cho Charles Petzold. Nếu có ai biết, anh sẽ làm thế. –

+0

@ J.Polfer: Sử dụng bí danh cho các loại tham số là rất phổ biến đối với mã thư viện. Nó cho phép tác giả thay đổi loại cụ thể trong giao diện trong khi duy trì tính tương thích nguồn. Bạn vẫn có thể biên dịch mã Windows 16 bit hợp lệ để nhắm mục tiêu phiên bản Windows 64 bit, mặc dù các loại cơ bản cho ví dụ: 'WPARAM' hoặc' LPARAM' đã thay đổi nhiều lần. 'BOOL' có một lịch sử khác nhau: Khi công việc trên Windows bắt đầu, không có kiểu boolean trong ngôn ngữ C. Nó được giới thiệu vào cuối C99. – IInspectable

Trả lời

15

API Windows ban đầu được thiết kế theo khung thời gian 1984-85, cách đây hơn 25 năm. Ký hiệu Hungary là tất cả các cơn thịnh nộ, vì vậy việc đưa loại biến vào tuyên bố là điều cần làm. Ví dụ, trong thuần túy C, không có cách nào để chỉ ra một con trỏ 'xa', đó là những gì LP trong LPCSTR chỉ ra, nhưng vào năm 1985, nó rất quan trọng để phân biệt giữa con trỏ thông thường và con trỏ xa. (Tầm quan trọng đó đã được giải quyết khi các cửa sổ 32 bit tiếp quản vào giữa những năm 90, nhưng cú pháp vẫn tồn tại ...)

Ngoài ra, C không thực sự phân biệt giữa chỉ một con trỏ đến một con trỏ và con trỏ vào một chuỗi tĩnh. Vì vậy, các loại lpsz. Cuối cùng, nó mang lại một cách đánh mạnh hơn, nhất quán cho các tham số so với đồng bằng C cho phép vào năm 1984. Đối với WinMain, đó là bởi vì một chương trình Windows khá khác với chương trình dòng lệnh. Nếu bạn nhìn vào thư viện, bạn có thể tìm thấy một hàm main() để thiết lập các tham số và sau đó gọi vào một hàm WinMain bên ngoài (tức là của bạn).

+0

1984-1985, đây là thời điểm không có chuẩn C, phải không? – Inno

+1

Chữ ký điểm nhập gốc là 'void __stdcall NoCRTMain (void)' thay vì là hàm C main() thông thường. Thư viện thời gian chạy C gọi 'WinMain' hoặc' main' khi thích hợp. –

4

Có hai lý do chính:

  • phức tạp. Ngôn ngữ C là tối thiểu, cung cấp các khối xây dựng mà trên đó các kiến ​​trúc phức tạp hơn có thể được xây dựng. LPCSTR, BOOL và các loại khác mà bạn tìm thấy trong Win32 là typedefs hoặc cấu trúc được xây dựng trên đầu trang của C.
  • Định hướng sự kiện. C thường được dạy giả định rằng chương trình của bạn chủ động và kiểm soát mọi thứ. Trong môi trường định hướng sự kiện, chẳng hạn như Windows (hoặc bất kỳ hệ điều hành dựa trên GUI nào khác), chương trình của bạn là được gọi là bởi hệ điều hành, vì vậy nó thường nằm trong vòng lặp chờ tin nhắn đến.

API của các hệ điều hành dựa trên GUI khác có thể cảm thấy khác với Win32, vì không có giải pháp duy nhất, nhưng vấn đề chúng giải quyết là giống nhau.

1

Chúng thực sự không "đi theo cách khác", khi bạn đặt nó.

WinMain() chỉ đơn giản là điểm vào được hệ điều hành Windows tìm kiếm. Về mặt khái niệm, nó không khác với main().

Đối với các định nghĩa biểu tượng (LPCSTR, BOOL, v.v.), một phần của điều này là để dễ sử dụng. Ví dụ: viết ngắn hơn LPCSTR hơn const char *. Một ví dụ khác là typaief BOOL không được ngôn ngữ C. hỗ trợ. Lý do khác là cách ly nhà phát triển khỏi những thay đổi đối với phần cứng cơ bản, ví dụ: thay đổi từ kiến ​​trúc 16 bit đến 32 bit thành 64 bit.

Không có nghĩa là câu trả lời này nên được xem là đầy đủ. Nó chỉ là một vài điều mà tôi đã nhận thấy từ lập trình tôi đã thực hiện với Win32/MFC.

1

Tôi muốn nói đa số là một câu hỏi về phong cách.Các tiêu chuẩn đã phát triển từ thế giới Unix, ví dụ như các hàm thư viện có tên ngắn và không có nhiều kiểu chữ. Tôi cho rằng phản ánh sự lựa chọn của các nhà thiết kế của C và Unix. Mặt khác, Windows có LongFunctionNamesInMixedCaseLOTSOFTYPEDEFS, *PTYPEDEFSFORPOINTERSTOO.

Một số trong số đó cũng là nhận thức về sự cần thiết. Ví dụ: WinMain() có những thứ như nCmdShow, vì ứng dụng đồ họa sẽ gọi ShowWindow() và tôi cho rằng họ muốn có thể chuyển đối số đó cho quy trình mới được đưa ra. Có hoặc không thực sự là cần có thể là một câu hỏi khác.

Và tất nhiên, một số API làm những việc rất khác nhau. Trong Windows, có rất nhiều sự nhấn mạnh vào việc truyền tải thông điệp và xử lý tin nhắn trên cơ sở theo từng luồng. CreateFile() có rất nhiều cờ mà thế giới Unix không có, bao gồm các chế độ chia sẻ để xác định quá trình khác có thể thực hiện khi bạn mở tệp.

+0

Windows có xu hướng làm cho tất cả các tùy chọn một phần của cuộc gọi tập tin với một cấu trúc thông tin lớn, Unix sử dụng các cuộc gọi đến ioctl. Đây có lẽ là một nơi mà cách tiếp cận cửa sổ dễ dàng hơn. –

+0

Đúng ở nhiều nơi, nhưng Windows cũng có ioctls .. Ví dụ, để thiết lập điểm thô hoặc làm cho một tệp thưa thớt. – asveikau

2

của Microsoft Raymand Chen writes in his blog:

Mặc dù chức năng WinMain là ghi nhận trong SDK Platform, nó không thực sự là một phần của nền tảng này. Thay vào đó, WinMain là tên thông thường cho điểm nhập do người dùng cung cấp vào chương trình Windows.

Điểm entry thật là trong thư viện runtime C , khởi tạo thời gian chạy , chạy constructors toàn cầu, và sau đó gọi hàm WinMain (hoặc wWinMain nếu bạn thích một mục Unicode điểm).

0

Lập trình API Windows được điều khiển sự kiện, trong khi đó, cho đến thời điểm đó, hầu hết chương trình C là tuyến tính. Do đó, WinMain() là một lối tắt vào các thư viện để viết bằng chức năng OS - trong khi main() là một phần của ngôn ngữ C.

Trong khi chúng tôi đang ở trên chủ đề, C có rất ít được xây dựng trong các loại, và, tại thời điểm đó, có vài cách để chỉ ra chúng. Các cửa sổ "loại" (HWND, LPSTR, BOOL, vv) phản ánh các kiểu dữ liệu thường được sử dụng trong lập trình cửa sổ, và cố gắng chỉ ra cho lập trình viên biết loại dữ liệu sẽ là gì.

Ký hiệu Hungary là một chút sử dụng sai các phiên bản gốc, trong đó có một số lượng không cần thiết của vòng loại trong nhiều biến.

Các vấn đề liên quan