2011-11-03 10 views
7

Sto progettando un middleware di comunicazione da utilizzare in un'applicazione che ha un modulo in Ada e molti moduli in C++ che comunica i parametri di passaggio (valori scalari) e le strutture. L'applicazione viene eseguita in MS Windows XP e Windows 7, la parte C++ è in fase di sviluppo in MSVC++ 2008, la parte di Ada è in fase di sviluppo con GPS/GNAT. La versione di Ada è del 1995 ma siamo nel mezzo di una migrazione del compilatore (versione più recente di GPS/GNAT) con la possibilità di utilizzare le specifiche Ada più recenti.Un record Variant Ada può essere compatibile binario con un sindacato C++?

Il middleware è in fase di scrittura in C++ e vorrei utilizzare un tipo di unione contenente tutti i tipi che vengono passati tra i moduli quindi non sarà necessario specificare una funzione put/get per ogni tipo che viene utilizzato nel sistema .

La domanda è, i binari C++ sono compatibili con i record di varianti Ada? In altre parole, se passo un codice C++ al codice Ada sarà in grado di leggerlo come record Variant? (E viceversa)

Credo che per questo sia possibile saranno necessarie alcune regolazioni ... (unioni es .: C++ non contengono un elemento che descrive il contenuto in record Ada varianti fanno)

+1

Probabilmente avrai bisogno di specificare la piattaforma, i compilatori ecc. –

+0

Grazie, appena aggiunto altro informazioni sul nostro ambiente. – Guarita

risposta

2

No. Come dichiari tu stesso, i record delle varianti Ada contengono un campo tag. Il sindacato C non ha questo. (Almeno non in MSVC++ e GCC - è consentito da ISO C.)

+0

Ah, sì, ma la mia domanda è se è possibile rendere i sindacati C compatibili con le varianti di Ada con qualche lavoro aggiuntivo non plug-n-play. Mi aspettavo già qualche difficoltà ad adattare la parte C al binario-talk al codice Ada. – Guarita

7

Possibilmente.

Ada 2005 fornisce il pragma Unchecked_Union che consente a un programma di "[specificare] una corrispondenza di interfaccia tra un determinato tipo discriminato e un certo unione C. Il pragma specifica che al tipo associato deve essere data una rappresentazione che non lascia spazio per il suo discriminante (s) ".

Dalla mia lettura della sezione RM, si dichiara un tipo Ada con le discriminanti necessarie per definire un record variante, ma nessuno spazio di archiviazione è assegnato per i discriminanti. Immagino che questo significhi sul lato Ada che la discriminante non possa in seguito essere referenziata. (Ci sono anche altre restrizioni, come tutti i campi devono essere compatibili con C, vedi RM B.3.3 per maggiori informazioni.)

Non ho mai usato questo pragma, e non posso fare a meno di pensare che richiederà un po ' sperimentazione per farlo funzionare (si spera) con il tuo sistema. In bocca al lupo!

+2

Parte della sperimentazione sarà scoprire se è necessario dire a GNAT di deporre i record nel modo in cui MSVC++ si aspetta, e in tal caso come. GNAT comprende le convenzioni del GCC, ovviamente; Finché ti limiti ai sindacati C e ai tipi semplici, non dovrebbe essere troppo cattivo. –

+1

GCC su Windows è conforme alla piattaforma C ABI, quindi GNAT su Windows dovrebbe essere ABI compatibile con MSVC++. – MSalters

3

Come menzionato da MSalters, non funzionerà a meno che l'unione C per qualche motivo contenga un campo che designa la variante. Poiché non è richiesto in C, non funzionerà spesso. Tuttavia, dal momento che è controllare l'attuazione di quel tipo C, è possibile farlo funzionare. Assicurati di avere un campo proprio davanti al sindacato che indica quale unione viene utilizzata.

Per renderlo completamente compatibile binario con la struttura di unione C, sarà probabilmente necessario utilizzare un tipo di record Ada semplice, insieme a una clausola di rappresentazione dei record per assicurarsi che i campi siano disposti negli stessi luoghi il tuo compilatore C capita di metterli. E sì, questo ti rende vulnerabile alle modifiche del compilatore C che causano modifiche al layout. Puoi provare a proteggerti con i bitfield nel tuo codice C, ma non sono abbastanza potenti da porre davvero le cose come possono fare le clausole dei record di registrazione di Ada. Questo è uno dei motivi per cui preferiamo utilizzare Ada per lavori di basso livello.

Devo dire che, quando ho controllato l'ultima volta, la versione per Windows di Gnat non era compatibile con linker con i binari di VisualStudio. L'unico modo che conosco per far lavorare insieme quei due compilatori è quello di mettere l'intera interfaccia in una DLL. In caso contrario, probabilmente dovrai utilizzare GCC per creare il tuo sistema C++ o utilizzare qualche altro compilatore Ada, come ObjectAda.

+0

"Come menzionato da MSalters, non funzionerà a meno che il sindacato C per qualche ragione contenga un campo che designa la variante." Forse potrei farlo con una struct come: struct foo { tag some_tag_type; unione { ... } my_union; } ?? – Guarita

+0

@guarita vedi la mia risposta per un link utile - penso che tu sia sulla strada giusta con questa idea. – NWS

+0

Sì. Come ha detto @NWS, sei sulla buona strada. –

5

Sì.

Ada è compatibile con i join C/C++. Vedere here su come farlo (pdf) In particolare, Pagina 5 mostra come farlo con i tag Unions &. Dovrebbe essere lo stesso per l'utilizzo di record Discriminanti. (Caveat: probabilmente non è il compilatore che stai usando, ma sarei molto sorpreso se il tuo non si comporta allo stesso modo!)

+1

Penso che tu sia un po 'ottimista riguardo l'aspettativa che ci si possa aspettare diversi compilatori Ada/C/C++ per gestirlo senza grandi preoccupazioni, ma è una guida utile al problema. –

+0

@Marc My Optimism si basa sul fatto che i compilatori Ada dovrebbero essere convalidati, quindi dovrebbero essere in grado di fare le stesse cose (anche se non altrettanto bene!) – NWS

+0

Non è il lato Ada di cui sono preoccupato, è il campo layout e linking minutia tra diversi compilatori che mi colora scettico (di ottimismo :-). Non sono estraneo ai binding, anche la condivisione delle strutture di dati tra GNAT e gcc richiede attenzione. –