2009-12-02 17 views
5

Me pregunto por qué el WinAPI es muy diferente de la programación "normal" de C?¿Por qué WinAPI es tan diferente de la C "normal"?

Quiero decir, en la escuela aprendí que cada programa C tiene una función main() (WinAPI usa WinMain con algunos parámetros especiales), algunos tipos de variables como int, long, char, etc. (WinAPI usa cosas como LPCSTR, BOOL , etc.) entonces, ¿por qué Microsoft decidió ir de otra manera con su API de sistema operativo?

cuando vi mi primer programa de API de Windows que se parece más a un lenguaje nuevo para mí ...;)

+1

Inno - No estoy seguro de por qué MS usa #defines para muchos de sus tipos de variables. Si quieres saber por qué decidieron hacer eso, enviaría un correo electrónico a Charles Petzold. Si alguien lo supiera, lo haría. –

+0

@ J.Polfer: el uso de alias para los tipos de parámetros es muy común para el código de la biblioteca. Permite al autor cambiar el tipo específico en la interfaz mientras se mantiene la compatibilidad de la fuente. Todavía puede compilar código válido de Windows de 16 bits para apuntar a una versión de Windows de 64 bits, aunque los tipos subyacentes de, p. 'WPARAM' o' LPARAM' han cambiado varias veces. 'BOOL' tiene una historia diferente: cuando comenzó a trabajar en Windows, no había ningún tipo booleano en el lenguaje C. Fue introducido tan tarde como C99. – IInspectable

Respuesta

15

La API original de Windows fue diseñada en el marco de tiempo de 1984-85, hace más de 25 años. La notación húngara era furor, así que poner el tipo de variable en la declaración era lo que tenía que hacer. Por ejemplo, en C puro, no hay forma de indicar un puntero "lejano", que es lo que indica el LP en LPCSTR, pero en 1985, era muy importante distinguir entre punteros regulares y punteros lejanos. (Esa importancia quedó en el olvido cuando las ventanas de 32 bits se hicieron cargo a mediados de los 90, pero la sintaxis persiste ...)

Además, C realmente no distingue entre un puntero y un puntero a una cuerda estática. Por lo tanto, los tipos lpsz.

Al final, se trata de llevar una, mecanografía coherente más fuerte a los parámetros que sencilla C permitidos en 1984. En cuanto a la WinMain, es porque un programa de Windows es bastante fundamentalmente diferente de un programa de línea de comandos. Si busca en la biblioteca, probablemente encuentre una función main() que configure los parámetros y luego llame a una función externa de WinMain (es decir, la suya).

+0

1984-1985, esta era una época en la que no existía el estándar C, ¿verdad? – Inno

+1

La firma del punto de entrada nativo es 'void __stdcall NoCRTMain (void)' en lugar de ser una función C main() convencional. La biblioteca de tiempo de ejecución de C llama 'WinMain' o' main' según corresponda. –

4

Hay dos razones principales:

  • Complejidad. El lenguaje C es mínimo, proporcionando los bloques de construcción sobre los que se pueden construir arquitecturas más complejas. LPCSTR, BOOL y otros tipos que se encuentran en Win32 son typedefs o estructuras construidas sobre C.
  • Orientación del evento. C generalmente se enseña suponiendo que su programa es proactivo y tiene el control de las cosas. En un entorno orientado a eventos, como Windows (o cualquier otro sistema operativo basado en GUI), su programa es llamado por el sistema operativo, por lo que normalmente se encuentra allí en un bucle esperando a que lleguen los mensajes.

Las API de otros sistemas operativos basados ​​en GUI pueden parecerse a Win32, porque no hay una solución única, pero el problema que están resolviendo es el mismo.

1

Realmente no "van de una manera tan diferente", como usted dice.

WinMain() es simplemente el punto de entrada buscado por el sistema operativo Windows. Conceptualmente, no es diferente de main().

En cuanto a las definiciones de los símbolos (LPCSTR, BOOL, etc.), parte de esto es para facilitar su uso. Por ejemplo, es más corto escribir LPCSTR que const char *. Otro ejemplo es el typedef BOOL que no es compatible con el lenguaje C. La otra razón es aislar al desarrollador de los cambios en el hardware subyacente, por ejemplo, el cambio de arquitecturas de 16 bits a 32 bits a arquitecturas de 64 bits.

De ninguna manera esta respuesta debe considerarse exhaustiva. Es solo un par de cosas que he notado de la programación que hice con Win32/MFC.

1

Diría que la mayor parte es una cuestión de estilo.Los estándares surgieron del mundo de Unix, así que, por ejemplo, las funciones de la biblioteca tienen nombres cortos, y no hay muchos typedefs. Supongo que eso refleja las elecciones de los diseñadores de C y Unix. Por otro lado, Windows tiene LongFunctionNamesInMixedCase y LOTSOFTYPEDEFS, *PTYPEDEFSFORPOINTERSTOO.

Algunos de ellos también son la percepción de la necesidad. Por ejemplo, WinMain() tiene cosas como nCmdShow, porque las aplicaciones gráficas llamarán al ShowWindow() y supongo que querían poder pasar el argumento a un proceso recién iniciado. Si eso es realmente necesario podría ser otra pregunta.

Y, por supuesto, algunas de las API hacen cosas muy diferentes. En Windows hay mucho énfasis en pasar mensajes y procesar mensajes por subproceso. CreateFile() tiene una gran cantidad de indicadores que el mundo de Unix no tiene, incluidos los modos de intercambio que determinan qué puede hacer otro proceso mientras tiene un archivo abierto.

+0

Windows tiende a hacer que todas las opciones formen parte de la llamada al archivo con una gran estructura de información, Unix usa las llamadas al ioctl. Este es probablemente un lugar donde el enfoque de Windows es más fácil. –

+0

Es cierto en muchos lugares, pero Windows también tiene ioctls ... Por ejemplo, para establecer puntos de reanálisis o hacer que un archivo sea escaso. – asveikau

2

de Microsoft Raymand Chen writes in his blog:

Aunque la función WinMain es documentado en el SDK de la plataforma, es no es realmente parte de la plataforma. En cambio, WinMain es el nombre convencional para el punto de entrada proporcionado por el usuario a un programa de Windows.

El punto de entrada real está en la biblioteca de ejecución C , que inicializa el tiempo de ejecución , corre constructores mundiales, y entonces llama a su función WinMain (o wWinMain si lo prefiere una entrada de Unicode punto).

0

La programación de la API de Windows es controlada por eventos, mientras que, hasta ese momento, la mayoría de la programación en C era lineal. WinMain() es, por lo tanto, un acceso directo a las bibliotecas para escribir utilizando la funcionalidad del sistema operativo, mientras que main() es parte del lenguaje C.

Mientras hablamos sobre el tema, C tiene pocos tipos incorporados y, en ese momento, tenía pocas formas de indicarlos. Los "tipos" de ventanas (HWND, LPSTR, BOOL, etc.) reflejan los tipos de datos comúnmente utilizados en la programación de Windows e intentan indicarle al programador cuáles serán los tipos de datos.

La notación húngara es un poco un mal uso de las versiones originales, ya que hay un número innecesario de calificadores en muchas variables.

Cuestiones relacionadas