2009-12-02 18 views
5

Mi chiedo perché WinAPI sia così diverso dalla programmazione C "normale"? Intendo dire, a scuola ho imparato che ogni programma C ha una funzione main() (WinAPI usa WinMain con alcuni parametri speciali), alcuni tipi variabili come int, long, char ecc. (WinAPI usa cose come LPCSTR, BOOL , ecc.), quindi perché Microsoft ha deciso di andare in modo diverso con le proprie API del sistema operativo?Perché WinAPI è così diverso da "normale" C?

quando ho visto il mio primo programma WinAPI mi sembra più simile a un nuovo linguaggio per me ...;)

+1

Inno - Non sono sicuro del motivo per cui MS utilizza #defines per molti dei loro tipi di variabile. Se vuoi sapere perché hanno deciso di farlo, manderei un'email a Charles Petzold. Se qualcuno lo sapesse, lo farebbe. –

+0

@ J.Polfer: l'utilizzo di alias per i tipi di parametro è molto comune per il codice di libreria. Permette all'autore di modificare il tipo specifico nell'interfaccia mantenendo la compatibilità della fonte. Puoi ancora compilare un codice Windows a 16 bit valido per scegliere come target una versione a 64 bit di Windows, anche se i tipi sottostanti per es. 'WPARAM' o' LPARAM' sono cambiati più volte. 'BOOL' ha una storia diversa però: quando ha iniziato a lavorare su Windows, non c'era alcun tipo booleano nel linguaggio C. È stato introdotto fino a quando C99. – IInspectable

risposta

15

L'API di Windows originale è stata progettata nel periodo 1984-1985, oltre 25 anni fa. La notazione ungherese era di gran moda, quindi mettere il tipo di variabile nella dichiarazione era la cosa giusta da fare. Per esempio, in puro C, non c'è modo di indicare un puntatore "lontano", che è quello che indica l'LP in LPCSTR, ma nel 1985 era molto importante distinguere tra puntatori regolari e puntatori lontani. (Quella importanza è andata in secondo piano quando Windows a 32 bit ha preso il sopravvento a metà degli anni '90, ma la sintassi persiste ...)

Inoltre, C in realtà non fa distinzione tra solo un puntatore a un carattere e un puntatore a una stringa statica. Quindi i tipi di lpsz.

Alla fine, si tratta di portare una digitazione più forte e coerente ai parametri rispetto alla C normale consentita nel 1984. Per quanto riguarda WinMain, è perché un programma Windows è fondamentalmente diverso da un programma a riga di comando. Se si guarda nella libreria, probabilmente si troverà una funzione main() che imposta i parametri e quindi chiama in una funzione WinMain esterna (ad esempio la propria).

+0

1984-1985, questo era un tempo in cui non esisteva lo standard C, giusto? – Inno

+1

La firma del punto di ingresso nativo è 'void __stdcall NoCRTMain (void)' piuttosto che una convenzionale funzione C main(). La libreria di runtime C chiama 'WinMain' o' main' come appropriato. –

4

Ci sono due motivi principali:

  • Complessità. Il linguaggio C è minimo, fornendo gli elementi costitutivi su cui è possibile costruire architetture più complesse. LPCSTR, BOOL e altri tipi che trovi in ​​Win32 sono typedef o struct costruiti sopra C.
  • Orientamento degli eventi. C di solito viene insegnato assumendo che il tuo programma sia proattivo e in controllo delle cose. In un ambiente orientato agli eventi, come Windows (o qualsiasi altro sistema operativo basato su GUI), il tuo programma è chiamato dal sistema operativo, quindi di solito si trova lì in un ciclo in attesa che arrivino i messaggi.

Le API di altri SO basati su GUI possono essere diverse da Win32, perché non esiste una soluzione singola, ma il problema che stanno risolvendo è lo stesso.

1

Davvero non "andavano in modo diverso", come dici tu.

WinMain() è semplicemente il punto di ingresso cercato dal sistema operativo Windows. Concettualmente, non è diverso da main().

Come per le definizioni dei simboli (LPCSTR, BOOL, ecc.), Parte di questo è per facilità d'uso. Ad esempio, è più breve scrivere LPCSTR rispetto a const char *. Un altro esempio è il typedef BOOL che non è supportato dal linguaggio C. L'altro motivo è di isolare lo sviluppatore dalle modifiche all'hardware sottostante, ad esempio la modifica da architetture da 16 bit a 32-bit a 64-bit.

In nessun caso questa risposta deve essere considerata esaustiva. Sono solo un paio di cose che ho notato dalla programmazione che ho fatto con Win32/MFC.

1

Direi che la maggior parte è una questione di stile.Gli standard sono nati dal mondo Unix, quindi ad esempio le funzioni della libreria hanno nomi brevi e non ci sono molti typedef. Presumo che rifletta le scelte dei designer di C e Unix. D'altra parte Windows ha LongFunctionNamesInMixedCase e LOTSOFTYPEDEFS, *PTYPEDEFSFORPOINTERSTOO.

Parte di questa è anche la percezione della necessità. Ad esempio, WinMain() ha cose come nCmdShow, perché le app grafiche chiamano ShowWindow() e suppongo che volessero essere in grado di passare l'argomento a un nuovo processo avviato. Indipendentemente dal fatto che sia effettivamente necessario potrebbe essere un'altra domanda.

E, naturalmente, alcune API fanno cose molto diverse. In Windows viene data molta importanza al passaggio dei messaggi e all'elaborazione dei messaggi su una base per thread. CreateFile() ha un sacco di flag che il mondo Unix non ha, incluse le modalità di condivisione che determinano ciò che un altro processo può fare mentre si ha un file aperto.

+0

Windows tende a rendere tutte le opzioni parte della chiamata al file con una grande struttura di informazioni, Unix usa le chiamate all'ioctl. Questo è probabilmente un posto dove l'approccio di Windows è più facile. –

+0

Vero in molti posti, ma Windows ha anche ioctls .. Ad esempio, per impostare i punti di analisi o rendere un file sparse. – asveikau

2

di Microsoft Raymand Chen writes in his blog:

Anche se la funzione WinMain è documentato in Platform SDK, è non realmente parte della piattaforma. Piuttosto, WinMain è il nome convenzionale per il punto di ingresso fornito dall'utente in un programma Windows.

Il vero punto di ingresso si trova nella libreria runtime C , che inizializza il runtime , corre costruttori a livello mondiale, e chiama quindi la funzione WinMain (o wWinMain, se si preferisce una voce di Unicode punto).

0

La programmazione dell'API di Windows è basata su eventi, mentre, fino a quel momento, la maggior parte della programmazione C era lineare. WinMain() è quindi una scorciatoia nelle librerie per la scrittura utilizzando le funzionalità del sistema operativo, mentre main() fa parte del linguaggio C.

Mentre siamo in argomento, C ha pochi tipi incorporati e, al momento, aveva pochi modi per indicarli. I "tipi" di Windows (HWND, LPSTR, BOOL, ecc.) Riflettono i tipi di dati comunemente usati nella programmazione di Windows e fanno un tentativo di indicare al programmatore quali saranno i tipi di dati.

La notazione ungherese è un po 'un uso non corretto delle versioni originali, in quanto vi sono un numero non necessario di qualificatori in molte variabili.