2009-02-19 12 views
14

Las aplicaciones de Windows GUI escritas en C/C++ tienen 'WinMain' como punto de entrada (en lugar de 'main'). Mi comprensión de esto es que el compilador genera una función 'principal' que el C Runtime llamará. Esta función 'principal' configura el entorno necesario para la GUI y llama a 'WinMain' (especificando los identificadores de instancia, etc.).¿Cómo puedo escribir una aplicación de Windows sin usar WinMain?

En resumen, creo que la consola y arranque de la aplicación GUI difieran de la siguiente manera:

consola de aplicación: C Runtime -> función 'principal' (mano-codificado) la aplicación

interfaz gráfica de usuario: C Runtime -> función 'principal' (generada por el compilador) -> función 'WinMain' (codificada a mano)

Me gustaría validar este entendimiento y descubrir cómo puedo codificar manualmente un Windows GUI con solo una función 'principal' (es decir, sin tener que escribir 'WinMain').

Respuesta

15

Tiene un entendimiento incorrecto. La diferencia entre main y WinMain, aparte de algún código de inicialización diferente, son los parámetros que se le pasan.

miradas como estos:

int main(int argc, char* argv[]); 

Mientras WinMain se ve así:

int WINAPI WinMain(HINSTANCE hInstance, 
    HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, 
    int nCmdShow 
); 

Algo tiene que configurar los parámetros y realizar la llamada, y ese es el código de inicio. Cuando compila y vincula un programa, uno de los parámetros del enlazador es el punto de entrada, y eso será, dependiendo de una consola o aplicación GUI, un bit diferente de código de inicio.

Ciertamente puede escribir su propio código de inicio, solo vaya a su directorio de código fuente visual C++ y puede encontrar el código de inicio, se llama crt0.c y está en el directorio VC \ crt \ src.

6

Funciona de la otra manera. Hay un archivo de objeto enlazado estáticamente que viene con el compilador que contiene el punto de entrada real. Ese punto de entrada realiza la inicialización y luego llama a su punto de entrada (es decir, WinMain).

Lo que esa parte estática espera llamar puede ser modificable. Por ejemplo, en Visual Studio hay un campo para el nombre del punto de entrada en la configuración del enlazador.

+0

Entonces, ¿cuál es el orden de ejecución en la consola y los casos de aplicación GUI? ¿Es la parte estática diferente en esos dos casos? ¿Dónde encaja el tiempo de ejecución de C? –

+0

Primero se ejecuta la parte estática, luego llama al punto de entrada implementado por el usuario. Puede ser diferente o puede ser el mismo, pero el vinculador podría vincular la llamada a diferentes puntos de entrada dependiendo de la configuración. Puedes pensar en esta parte estática ya que es parte del tiempo de ejecución de C. – sharptooth

8

Con solo principal, no puede codificar Winmain. Para justificaciones, se toman las siguientes declaraciones de http://blogs.msdn.com/oldnewthing/archive/2007/12/03/6644060.aspx

[En Windows de programación,] ¿Por qué no fue el punto de entrada de la aplicación llama principal? Bueno, para empezar, el nombre main ya estaba ocupado, y Windows no tenía la autoridad para reservar una definición alternativa. No había un comité de normalización del lenguaje C en aquel entonces; C era lo que Dennis dijo que era, y no estaba garantizado que Dennis tomaría medidas especiales para conservar la compatibilidad con el código fuente de Windows en cualquier versión futura del lenguaje C. Dado que K & R no especificaba que las implementaciones pudieran extender los formularios aceptables de la función principal, era completamente posible que hubiera un compilador legal C que rechazara los programas que declararon principal incorrectamente.El estándar de lenguaje C explícitamente permite definiciones alternativas específicas para main, pero requiere que todos los compiladores admitan esta nueva versión específica de Windows para compilar programas de Windows restringiría de forma gratuita el conjunto de compiladores que podría usar para escribir Programas de Windows.

Si se las arregló para superar este obstáculo, que tendría el problema de que la versión Windows del principal tendría que ser algo como esto:

int main(int argc, char *argv[], HINSTANCE hinst, 
     HINSTANCE hinstPrev, int nCmdShow); 

Debido a la vinculación forma C se realice total las variaciones de una función debían estar de acuerdo en los parámetros que tenían en común. Esto significa que la versión de Windows tendría que agregar sus parámetros al final de la versión más antigua existente de , y luego tendría que cruzar los dedos y esperar que el lenguaje C nunca haya agregado otra versión alternativa de main. Si siguió esta ruta, sus dedos cruzados le fallaron, porque da un tercer parámetro que se agregó a main algún tiempo después, y entró en conflicto con su versión amigable para Windows.

Supongamos que ha logrado convencer a Dennis de no permitir que versión de tres parámetros de main. Aún debe presentar esos primeros dos parámetros , lo que significa que el código de inicio de cada programa debe contener un analizador de línea de comando. De vuelta en los días de 16 bits, personas escatimadas para guardar cada byte. Diciéndoles, "Ah, y todos sus programas van a ser 2KB más grandes" probablemente no le haría mucho de amigos. Quiero decir, ¡eso es cuatro sectores de E/S de un disquete!

Pero probablemente la razón por la cual el punto de entrada de Windows recibió un nombre diferente es para enfatizar que es un entorno de ejecución diferente . Si se llamara main, la gente tomaría los programas C diseñados para un entorno de consola, los lanzaría a su compilador Windows y luego los ejecutaría, con resultados desastrosos.

Espero que esto despeje sus dudas.

Cuestiones relacionadas