Come separare il codice "non gestito" e "gestito" nel mio progetto C ++ / CLI
Sto sviluppando un progetto utilizzando C ++ / CLI e WinForms. È un progetto di geometria, motivo per cui devo usare C ++ / CLI, a causa della libreria di geometria C ++ CGAL . Ho scelto di utilizzare WinForms per l'interfaccia utente perché rispetto alle altre opzioni dell'interfaccia utente di Windows C ++ / CLI sembrava piuttosto facile da usare. Tuttavia, dopo alcune ricerche online mi sono reso conto che WinForms per C ++ / CLI utilizza codice gestito e che il codice gestito è spesso un fattore 2 più lento del codice nativo. Il progetto riguarda l'implementazione di un algoritmo competitivo, quindi il tempo di esecuzione è molto importante. Il progetto avrà un modulo UI molto semplice per selezionare alcuni parametri per il progetto e il tempo di esecuzione verrà monitorato solo per la parte di calcolo effettiva del progetto, non per l'interazione dell'interfaccia utente.
L'utilizzo di WinForms, in questo caso, rallenterà il tempo di esecuzione dei calcoli geometrici? Oppure va bene, perché la parte geometrica del codice è in una parte "non gestita". Come posso assicurarmi che sia "non gestito"?
Risposte
C ++ / CLI consente di combinare codice gestito e non gestito all'interno della stessa DLL / EXE ("assembly"). In parole povere, una classe "gestita" inizia con la ref classparola chiave, una classe non gestita viene introdotta senza la refparola chiave.
Nello scenario descritto nella domanda, di solito si implementa il programma utilizzando (almeno) tre livelli:
un livello C ++ non gestito che contiene gli algoritmi di base
un livello dell'interfaccia utente, probabilmente scritto in C #, poiché il designer di WinForms funziona meglio con quel linguaggio
un livello intermedio gestito C ++ / CLI come "intermediario" che collega i primi due e fornisce un'API gestita per l'interfaccia utente per accedere al livello non gestito.
In questo modo, il livello non gestito trarrà vantaggio dalle capacità di ottimizzazione complete del compilatore C ++ nativo. Dovrebbe essere ovvio che si dovrebbero evitare i callback alle funzioni gestite dall'interno delle sezioni critiche per le prestazioni del programma.
Se il "livello non gestito" fa parte dello stesso assembly in cui è posizionato il codice C ++ / CLI gestito, o se è posizionato in una lib o dll separata di solito non fa una grande differenza per le prestazioni. Tecnicamente, entrambi gli approcci sono possibili.
Grazie a @rwong per aver sottolineato in un commento che potrebbe essere necessario inserire #pragma unmanagednei file di classe C ++ non gestiti, nel caso in cui non si utilizzino librerie separate.