2016-10-17 6 views
3

私はadaからCへのインタフェースに問題があります。Adaがcにバイトバッファを送信する

type Byte is mod 256; pragma Convention (C, Byte); 
type ByteStream is array (Interfaces.C.size_t range <>) of Byte; 
    pragma Convention (C, ByteStream); 
type VoidPointer is access all ByteStream; 
type ByteBuffer is 
    record 
     data : VoidPointer; 
     size : Interfaces.C.size_t; 
    end record; 
pragma Convention (C, ByteBuffer); 
procedure Free is new Ada.Unchecked_Deallocation (ByteStream, VoidPointer); 

このC宣言:

struct ByteBuffer { 
    unsigned char *data; 
    size_t size; 
}; 

このADAインポート:

function My_Function (
    data : in ByteBuffer) 
    return Interfaces.C.int; 
pragma Import (C, My_Function, "my_function"); 

このC宣言:

int my_function(struct ByteBuffer data); 
特に私はこのADA宣言を有します

まだコードをデバッグするとき私はada側で(一例では)110のサイズを見つけますが、c側では0x7fffffffe750です。なぜ私のsize_tは乱されていますか? (注:データそのものも変更されていますが、修正するとうまくいけば、もう一方は修正されます)。

+0

おそらくC構造のパディングです。 Adaがそのレコードをどのように処理しているかはわかりません。またはあなたのコードのいくつかのバグ。 –

+0

私は 'pragma Convention(C、ByteBuffer);'がそれを解決したと思ったでしょう。多分私はC面で何かを指定する必要があるでしょうか? – LambdaBeta

+0

パディングはコンパイラ固有です。それについての "C条約"はありません。 –

答えて

3

Adaのinパラメータは、参照またはコピーのどちらでも使用できますが、コンパイラ/構造体のサイズによって異なります。エイダ側で

:あなたがこれを行うことができます(ここでは最も簡単な方法)ポインタを使用するには、両方の当事者を強制的に

function My_Function (
    data : access ByteBuffer) 
    return Interfaces.C.int; 
pragma Import (C, My_Function, "my_function"); 

そしてC側:

int my_function(const struct ByteBuffer *data); 

ByteBufferは制約付き配列であるため、別の情報が渡されます。境界はポインタです(ポインタ全体が「太い」ポインタです)。あなたは型宣言(エイダ側)

+0

私はそれを試しました。バイトバッファ内のデータは正しい(YAY!)が、size_tはまだマングリングされています。私はバッファとそのサイズを手動で分割しなければならないかもしれません。 – LambdaBeta

+0

私の編集を参照してください –

+0

すごく面白かったです。 skipitが境界を格納している場合は、C側で直接アクセスする方法はありますか? – LambdaBeta

0

エイダ無制限の文字列の後にpragma Convention(C_Pass_By_Copy,ByteBuffer)を使用することができ、

struct ByteBuffer { 
    unsigned char *data; 
    void *skipit; // ignore this value 
    size_t size; 
}; 

はコピーで渡すようにエイダを強制するには、コンパイラを持って:あなたはこれを行うことにより、C側でそれを「スキップ」でした依存データマッピング。私が使用しているものでは、文字列のサイズについて言われているもの(タグのようなもの)で始まり、バイトの「通常の」配列が来ることを確認しました。 CからAdaにバッファを渡すと、この最後の配列は、C配列の最初の要素から無制限配列の長さを取ることになります。 あなたの例が必要な理由はわかりませんが、すでに作成されたデータの配列をポイントすると仮定した場合、ByteStreamを固定のレッグ配列として宣言することができます(あなたの最大サイズと同じ大きさと言うことができます)あなたの "サイズ"パラメータで実際のサイズを管理する。 言い換えれば、ByteBufferレコードの "size"パラメータが、無制限の指し示された文字列構造に入り、 '長さ属性(Length atribute)'で抽出できるようになっているという意味では意味がありません。

関連する問題