2012-09-20 9 views
6

処理のために、AdaプログラムからいくつかのC++コードに2つのデータを渡す必要があります。AdaからC++へ:符号なし64ビット値を渡す

  • データ - ダブル。
  • 時間符号なし64ビット。

私はLONG​​_FLOAT(C++のdouble)と整数(C++のint、しかし、明らかではない64ビット)を使用して、私のC++の方法で働いていたエイダの手順を作ることができました。 私は、次のコード(私のコードではありませんので、構文が少しオフになる場合もあります)を使用:

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

今それが働いていることを、私は完全な64ビットまでの時間を拡大しようとしていると理想的にしたいと思いますC++側で符号なしlong longを持つ

type U64 is mod 2 ** 64; 

私のSEND_DATA方法とその型を使用して私はその型をマッピングすることも可能な方法が存在しないというエラーが出ます:私は、私は自分のタイプを作成したことと一致するエイダのいずれかの種類が表示されませんC++の型(これらの行には何かがありますが、私にはコードや正確なエラーフレーズはありません)。

Adaでユーザー定義型をC++に渡す方法はありますか?おそらく、私が使える符号なし64ビット値として使用できる別のタイプのAdaがありますか?それは私のU64型のアドレスをパラメータとしてC++メソッドに渡す方法がありますか?私は緑の丘adamultiコンパイラv3.5を使用しています(非常に新しく、その情報が役立つかどうかわからない)。例は非常に高く評価されるでしょう! KeithThompsonさんのコメント/答え@への補遺として

+6

「mod 2 ** 64」は正しいはずです。 GNATでその型を使ってあなたのサンプルをコンパイルすると、それは不平を言うことはありません。おそらく、あなたのAdaコンパイラは、C++(またはそれがターゲットとするC++コンパイラ)が64ビットの符号なし型をサポートしているとは思わないでしょう。標準のC++は2011年のISO標準まで 'unsigned long long'を取得していませんでした。 –

+0

@KeithThompson - Bah!あなたの答えのこれらの良いコメントをしてくださいキース、私のupvotes何かを意味する、私は彼らに適切にコメントすることができます、そして、彼らは答えになる場合、彼らは受け入れることができます。 –

+0

'pragma Convention(CPP、U64);'を追加することができます。 –

答えて

1

...

エイダの公式にサポートされているCインターフェイスタイプがInterfaces.Cであり、余分な長いintまたはunsignedは、2005年版では(そこではありませんが。2012年ですバージョンの公式はまだですか?)。

あなたはそれを回避するために正しいことをしました。コンパイラがそれをサポートしていない場合は、より徹底的な対策を講じなければなりません。

まず、64ビットintを参照渡しすることです。それはC側の変更を必要とします。

私はC/C++ TIME構造体が64ビット値になる傾向があることを知っています。これはunion構造体として定義されています。だからあなたができることは、これらのC構造体の1つを模倣するためにAdaレコードを定義し、Cのようにレイアウトされていることを確認してから(例:レコード表現とサイズ句で)そのパラメータ。

その後、あなたは厄介なパラメータを使う必要があります。たとえば、Adaのインポート側のパラメータを64ビットのfloat型に変更し、実際のパラメータを64ビットのfloat型にunchecked_convertingしてそのまま渡すことができます。問題は、多くのCPUのパスがintとは異なるレジスタに浮動することです。それはおそらくうまくいかないでしょうし、そうするならほとんどのcertianlyは移植性がありません。

あなたのコンパイラのCPP呼び出し規約がどのように機能するかを理解することができれば、それを偽造する方法は他にもあります。たとえば、2つの32ビットレジスタを使用して64ビットのintを渡す場合、Adaの64ビット整数を2つに分割し、Ada側で2つのパラメータに渡すことができます。参照によって64ビットの値を渡す場合、Ada側にあなたのU64へのポインタを渡していることを伝えることができます。繰り返しますが、これらのソリューションはポータブルではありませんが、あなたが動くようになります。

+1

KeithThompsonとT.E.Dの両方の提案に感謝します。私は "タイプU64_ptrはアクセスU64"を作成して、値としてU64タイプではなくポインタとしてU64_ptrを渡してみました。同じエラーが発生しました。U64にマップする互換性のあるC++タイプはありません。 また、long_floatにunchecked_conversionを試して、C++側のdoubleに渡して、unsigned long longにキャストし、いくつかのファンキーな値を受け取りました(私が期待したものではなく、さらに調査しませんでした)。 もう一度感謝しています。 – Xeelot

+0

@Xeelot - 「ファンキーな値」は、通常、一方の側が他方の側よりも逆参照されていたことを示します。 –

+0

@Xeelot - 「ファンキーな価値」は、大きな/リトルエンディアンの境界を越えていないと確信していますか? – NWS

関連する問題