2012-02-13 10 views
6

Cのボイドにエイダの文字列を変換します。 Cタイプは、タイプがvoid*のプロパティを持ち、ライブラリのユーザは通常、この値としてC文字列が指すアドレスを割り当てます。例:は、私がどのCライブラリのインタフェース午前C.</p> <p>に<code>void*</code>に<code>char*</code>をキャストに相当します<code>System.Adress</code>に「キャスト」エイダ<code>String</code>をする良い方法は何ですか*

Ada Stringから始まるAdaでどのように同等の効果を達成できますか?

私はこの技術を現時点で使用していますが、私にとっては怪しいようです。

declare 
    str : constant String := "banana"; 
    data : constant char_array := To_C(str); 
    mine : my_type; 
begin 
    mine.value := data(data'First)'Address; 
end; 

私は何のアドレスを取得することができるはずですので、あなたはvoid*」を使用しているコメントに言及

+2

'Interfaces.C.Strings'パッケージには、' chars_ptr'型が含まれています。インポートするC関数は、void *の代わりにchars_ptr型を使用する必要があります。 – oenone

+2

また、ここに提案されている解決策を見てください:http://en.wikibooks.org/wiki/Ada_Programming/Types/access#Where_is_void.2A.3F – oenone

+0

タイプの 'void *'メンバは 'void *'です。何かのアドレスを取ることができるはずです。文字列だけではありません。そのため、 'g ++'がAda specを生成し、 'System.Address'を使用した理由です。私は現時点で技術が現在働いていることを知っています。おそらくそれは音ですか? – Anthony

答えて

2

、でもエイダ2012任意の溶液でOKです。

それでは、汎用ポインタがどのようにしてAdaにどのように変換されるのかを尋ねる必要があります。特に、入力とサブタイプの機能を利用する方法があります。私は、この文脈では「何か」は一般的には解決できないと提出する。つまり、構造の柔軟性を維持したい場合は、Adaが提供する型システムの利点を犠牲にしなければなりません。さらに、現状のまま提示されたものを提出しますが、「何か」として信頼できるものを使用することは一般的に不可能です。

これは、含まれている「何か」の長ささえ判別する方法がないためです。文字列の場合、長さは最初のNUL文字(ASCII 0)が始まるまで、 。しかし、文字列でなければ長さを決定する方法はありません(配列[1,2,3]またはOBJECTの長さ/サイズを知るにはどうすればよいでしょうか...)。

長さの決定は、バッファオーバーフローを招待していないため、安定した/安全なコードを書く上で重要な要素です。


しかし、あなたはその後、私たちはより良い型変換を構築するために、その情報を使用することができ、パラメータ経由またはmy_structを変更するかどうか、データに関するいくつかの情報を提供することができれば、それをオフのまま。 (一般的には、データの有効性が以前とは違う方法であるかどうかをチェックすることができますし、より良い方法でコンパイラがそれをチェックすることができるため、より多くの情報が得られます)

Type Data_Type is Array(Positive Range <>) of Interfaces.Unsigned_8; 
    For Data_Type'Component_Size Use 8; 


Function Some_Data(Stream : not null access Ada.Streams.Root_Stream_Type'Class; 
        Length : In Positive) Return Data_Type is 
    begin 
    Return Result : Data_Type(1..Length) do 
     For Index in Result'Range loop 
      Interfaces.Unsigned_8'Read(Stream, Result(Index)); 
     end Loop; 
    End Return; 
    end Some_Data; 

上記を使用して、ストリームからのデータを含む8ビットの符号なし整数の配列を生成できます。一般的なケースでは何をしなければならないかを概説していますが、Cインポートを使って作業しているので、少し修正すればよいので、Temp変数はResultのような配列ですFor Temp'Address Use [...]をmy_type.valueにオーバーレイし、forループを使用してコピーします。

関連する問題