2012-09-20 11 views
6

Ho bisogno di passare 2 pezzi di dati da un programma Ada ad un codice C++ per l'elaborazione.Ada a C++: passare un valore a 64 bit senza segno

  • Dati - doppio.
  • Tempo: 64 bit senza segno.

ho potuto fare una procedura in Ada che funzionava con il mio metodo C++ utilizzando un Long_Float (single nel C++) e integer (int in C++, ovviamente non 64 bit però). Ho usato il seguente codice (codice non su di me in modo sintassi potrebbe essere leggermente fuori):

procedure send_data (this : in hidden_ptr; data : in Long_Float; time : in Integer); 
pragma import (CPP, send_data, "MyClass::sendData"); 

Ora che che sta lavorando, sto cercando di espandere il tempo per la piena a 64-bit e Preferirei avere un long lungo non firmato sul lato C++. Non vedo alcun tipo di Ada che corrispondono che così ho creato il mio tipo:

type U64 is mod 2 ** 64; 

Quando si utilizza questo tipo con il mio metodo Send_Data ho un errore dicendo che ci sono modi possibili per mappare questo tipo ad un Tipo C++ (qualcosa di simile, di nuovo non ho il codice o la frase esatta dell'errore su di me).

C'è un modo per passare un tipo definito dall'utente in Ada a C++? Forse c'è un altro tipo in Ada che posso usare come un valore a 64 bit senza segno che funzionerebbe? Esiste un modo per passare l'indirizzo del mio tipo U64 come parametro al metodo C++ se invece è più semplice? Sto usando il green hills adamulti compilatore v3.5 (molto nuovo ad ada, non sono sicuro se quell'informazione aiuti o meno). Gli esempi sarebbero molto apprezzati!

+6

'mod 2 ** 64' dovrebbe essere corretto. Quando compilo il tuo esempio usando quel tipo con GNAT, non si lamenta. Forse il tuo compilatore Ada non pensa che C++ (o il compilatore C++ a cui mira) supporti un tipo senza segno a 64 bit; lo standard C++ non ha ottenuto "unsigned long long" fino allo standard ISO del 2011. –

+0

@KeithThompson - Bah! Rendi questi tuoi buoni commenti, risponde Keith, quindi i miei upvotes significano qualcosa, posso commentarli correttamente e possono essere accettati se finiscono per essere la risposta. –

+0

Si potrebbe provare ad aggiungere 'pragma Convention (CPP, U64);'. –

risposta

1

Come un addendum al di @ KeithThompson commento/risposta ...

tipi di interfaccia C ufficialmente supportati

di Ada sono in Interfaces.C, e non c'è extra-long int o unsigned in là (nella versione del 2005. È il 2012 versione ufficiale ancora?).

Hai fatto la cosa giusta per risolvere il problema. Se il tuo compilatore non lo supporta, dovranno essere prese misure più drastiche.

La prima cosa ovvia da provare è passare l'int a 64 bit come riferimento. Ciò richiederà tuttavia modifiche sul lato C.

So che le strutture C/C++ TIME tendono ad essere valori a 64 bit, definiti come strutture unionizzate. Quindi, ciò che si potrebbe fare è definire un record Ada per simulare una di quelle strutture C, assicurarsi che venga impostato come C (ad esempio con la rappresentazione di record e le clausole di dimensione), e quindi rendere quell'oggetto ciò che la routine importata usa per il suo parametro

Dopodiché dovrai tirare brutti scherzi ai parametri. Ad esempio, puoi provare a modificare il lato dell'importazione di Ada del parametro in un float a 64 bit, deselezionando il parametro reale in un float a 64 bit e cercando di passarlo in questo modo. Il problema è che un sacco di pass della CPU galleggia in registri diversi da quelli inte. Quindi, probabilmente, non funzionerà, e se lo fa, la cosa più opportunamente non è portatile.

Potrebbero esserci altri modi per simulare, se si capisce come funziona la convenzione di chiamata CPP del compilatore. Ad esempio, se utilizza due registri adajacent a 32 bit per passare gli inte a 64 bit, è possibile dividere l'int Ada a 64 bit in due e passarlo in due parametri sul lato Ada. Se passa i valori a 64-bit per riferimento, puoi semplicemente dire al lato Ada che stai passando un puntatore al tuo U64. Ancora una volta, queste soluzioni non saranno portatili, ma ti faranno andare avanti.

+1

Grazie per i suggerimenti sia KeithThompson che T.E.D. Ho provato a creare un "tipo U64_ptr è accedere a U64" e passare l'U64_ptr come un puntatore piuttosto che il tipo U64 come valore. Ho ricevuto lo stesso errore, Non esiste un tipo C++ compatibile per mappare su U64. Ho anche provato una unchecked_conversion a long_float, passando ad un double sul lato C++ e lanciandolo a un unsigned long long e ricevuto alcuni valori funky (non quello che mi aspettavo, non ho investigato ulteriormente). Continuerò a giocarci quando posso e postare altre informazioni che riesco a trovare, grazie ancora! – Xeelot

+0

@Xeelot - "I valori funky" di solito indicano che un lato stava eseguendo il dereferenziamento più dell'altro lato. –

+0

@Xeelot - "Valori funky" sei sicuro di non attraversare anche un confine big/little endian? – NWS

Problemi correlati