2011-01-24 19 views
19

Provengo dal mondo Linux e conosco molti articoli sul mantenimento della compatibilità binario a ritroso (BC) di un'API di libreria dinamica scritta in linguaggio C++. Uno di questi è "Policies/Binary Compatibility Issues With C++" basato su Itanium C++ ABI, che viene utilizzato dal compilatore GCC. Ma non riesco a trovare nulla di simile per il compilatore Microsoft C++ (da MSVC).Compilatore GCC vs MS C++ per mantenere la compatibilità binaria delle API

Capisco che la maggior parte delle tecniche sono applicabili al MS compilatore C++ e vorrei scoprire specifiche del compilatore questioni relative alle differenze ABI (layout di v-table, pressare, etc.)

Così , le mie domande sono le seguenti:

  • sai eventuali differenze tra MS C++ e compilatori GCC quando mantenendo aC?
  • Dove posso trovare informazioni su MS C++ ABI o sulla manutenzione di BC of API in Windows?

Qualsiasi informazione correlata sarà molto apprezzata.
Grazie mille per il vostro aiuto!

+2

Sembra tutto un buon consiglio indipendentemente dal compilatore che si sta utilizzando. In realtà il testo dice "Questo testo si applica alla maggior parte degli ABI C++ usati dai compilatori su cui KDE può essere costruito." e fa riferimento a una fonte per le informazioni ABI MSVC, quindi questo potrebbe già coprire l'MSI ABI. – Rup

+0

Buona domanda - ma il mescolarsi di API e ABI non è chiaro. Sia il titolo che il testo potrebbero fare con una modifica; il titolo non fa commenti sull'ABI, quando penso che dovrebbe almeno fare riferimento alla compatibilità binaria. – sdg

+0

@Rup - Sono anche annotati: 'è l'informazione più completa trovata finora su MSVC ABI e manomissione dei nomi' e' alcuni dei vincoli specificati qui potrebbero non essere applicabili a un determinato compilatore'. Voglio scoprire i problemi specifici del compilatore. – aponomarenko

risposta

22

Prima di tutto queste politiche sono generali e non si riferiscono solo a gcc. Ad esempio: il segno privato/pubblico nelle funzioni è qualcosa di specifico per MSVC e non per gcc.

Quindi in pratica queste regole sono pienamente applicabili anche a MSVC e al compilatore generale.

Ma ...

si dovrebbe ricordare:

  1. GCC/C++ mantiene la sua stabilità ABI dal 3,4 rilascio ed è circa 7 anni (dal 2004), mentre MSVC rompe l'ABI ogni major release : MSVC8 (2005), MSVC9 (2008), MSVC10 (2010) non sono compatibili tra loro.
  2. Alcuni flag utilizzati frequentemente con MSVC possono interrompere anche ABI (come il modello Eccezioni)
  3. MSVC ha tempi di esecuzione incompatibili per le modalità di debug e rilascio.

Quindi sì, è possibile utilizzare queste regole, ma come nel solito caso di MSVC ha molte più stranezze.

Vedere anche "Some thoughts on binary compatibility" e Qt mantiene ABI stabile anche con MSVC.

Nota Ho una certa esperienza con questo come seguo queste regole in CppCMS

+0

Per mia curiosità: cosa è cambiato negli ABI MSVC tra le versioni? Non l'ho visto, e non riesco a pensare a nient'altro che alle librerie di runtime (e si può solo aggirare il problema se stai attento). – Rup

+3

@Rup: sì, i runtime sono incompatibili, i valori predefiniti sono cambiati, ad esempio tra MSVC7 e MSVC8 il significato predefinito di wchar_t è cambiato e così via. Quindi, fondamentalmente, è una pessima idea mescolare librerie compilate con versioni di compilatori diverse. – Artyom

+0

Ottimo articolo, grazie! – aponomarenko

8

Su Windows, che, fondamentalmente, hanno 2 opzioni per il lungo termine la compatibilità binaria:

  1. COM
  2. imitando COM

Controlla il mio post qui. Lì vedrai un modo per creare DLL e accedere a DLL in modo compatibile binario attraverso diversi compilatori e versioni del compilatore.

C++ DLL plugin interface

7

La migliore regola per MSVC compatibilità binaria è usare un'interfaccia C. L'unica funzione C++ con cui puoi farcela, secondo la mia esperienza, è l'interfaccia a ereditarietà. Quindi rappresentano tutto come interfacce che usano i tipi di dati C.

Ecco una lista delle cose che sono compatibili non binario:

  • Lo STL. Il formato binario cambia anche solo tra debug/release e in base ai flag del compilatore, quindi è meglio non usare il modulo STL.
  • Heaps. Non new/malloc in un modulo e /free in un altro. Ci sono diversi cumuli che non si conoscono l'un l'altro. Un altro motivo per cui STL non funzionerà con i moduli incrociati.
  • Eccezioni. Non lasciare che le eccezioni si propagino da un modulo a un altro.
  • Tipi di dati RTTI/dynamic_casting da altri moduli.
  • Non fidarti di altre funzionalità C++.

In breve, C++ non ha un ABI coerente, ma C lo fa, quindi evitare le caratteristiche del C++ che incrociano i moduli. Poiché l'ereditarietà singola è una semplice tabella v, è possibile utilizzarla in modo utile per esporre gli oggetti C++, a condizione che utilizzino tipi di dati C e non effettuino allocazioni di cross-heap. Questo è l'approccio utilizzato anche dalla Microsoft stessa, ad es. per l'API Direct3D. GCC può essere utile nel fornire un ABI stabile, ma lo standard non richiede questo, e MSVC sfrutta questa flessibilità.

+0

MSVC C++ sembra ancora peggio quando si prende in considerazione il potenziale di orrori come SECURE_SCL e HAS_ITERATOR_DEBUGGING per introdurre ulteriori incompatibilità binarie. – timday

+2

Sì, fa parte di "in funzione dei flag del compilatore", un altro motivo per cui non ci si può fidare dell'ABI. – AshleysBrain

+0

Stavo cercando una risposta breve per la compatibilità ABI delineata nel libro "Essential COM". Questo sembra abbastanza vicino. –

Problemi correlati