2016-03-21 14 views
0

私はC関数にADA側で宣言されたStringを渡す必要があるC-ADAバインディングプロジェクトに取り組んでいます。 ADAの機能の一つで、私はと有界char配列を宣言:Interfaces.C.Strings.Char_Array_Accessを使用中にエラーが発生しました

Str_C : Interfaces.C.Char_Array(1..23) := (others => Interfaces.C.nul); 

とASタイプChar_Array_Accessのベクトルを宣言:

Ptr1 : Interfaces.C.Strings.Char_Array_Access := Str_C'Access; 

しかし、コンパイラは、上述のベクトルの初期化時にコンパイルに失敗します"接頭辞の接頭辞"には別名を付ける必要があります。

(char_array型は既にchar型のエイリアスなので、以前はchar_arrayのエイリアスを作成していませんでした)

OK、のようchar配列の宣言にエイリアスキーワードを追加してみましょう。

Str_C : aliased Interfaces.C.Char_Array(1..23) := (others => Interfaces.C.nul); 

が、それはまだのように、ベクトルライン上のエラーで失敗します。 enter image description here

とchar型の配列に警告宣言行は次のようになります。 enter image description here

ここで何が問題になっているのか分かりません。どんな助けもありがとう!

+0

は、このC++ではないですか? –

+0

いいえ、それはC-ADAバインディングです –

+0

[タグ:c] – LPs

答えて

1

左側のexplictサブタイプ制約1..23については、サブタイプ境界Str_Cのタイプchar_arrayにあると思います。 (プライベート)ポインタタイプchars_ptrは、境界なしの制約のないオブジェクトに対して、Cのchar*(境界を認識していない)を反映しています。したがって、オブジェクトを次のように宣言します。

Str_C : aliased Interfaces.C.char_array := (1..23 => Interfaces.C.nul); 

Ptr1 : Interfaces. 
    C.Strings.chars_ptr := Interfaces.C.Strings.To_Chars_Ptr(Str_C'access); 

To_Chars_Ptrは必要なポインタ変換を行います。宣言は実際にコンパイラの診断を反映します。

To_AdaTo_C、およびConventionという識別子を言語機能とともに使用する価値があります。Adaは配列をCの関数としてCのポインタに渡します。これは、LRM Annex B.3実装アドバイスを参照)に記載されています。だから、もしあなたが好きなら、Ada側でAda文字列を保存することができます。

問題には、(例えば、サブプログラム内で宣言された配列の)先読みオブジェクトのアクセシビリティも含まれているように見えるので、ここでいくつかの方法があります。詳細については、LRM 3.10.2を参照してください。重要な質問は次のとおりです。「オブジェクトへのポインタが渡されてもオブジェクトは存在しますか?」サブプログラムの実行後にオブジェクトが存在することを確認するには、によって、サブプログラム内の配列をに割り当てます。これは、スタック上の変数として宣言するのとは異なります。 (スタック変数は本質的に呼び出しの後に消えます)。または、実際にはが何をしているのかを知っている場合は、'Unchecked_Accessではなく'Accessを使用して、ポインタがオブジェクトよりも長く存続する可能性があることをコンパイラに強制することができます。

Ptr2 : Interfaces.C.Strings.chars_ptr := -- DANGER AHEAD! 
    Interfaces.C.Strings.To_Chars_Ptr(Str_C'UNCHECKED_ACCESS); 

Ptr3 : Interfaces.C.Strings.Chars_Ptr := Interfaces.C.Strings.To_Chars_Ptr 
    (new Interfaces.C.char_array'(1..23 => Interfaces.C.nul)); 

Ptr4 : Interfaces.C.Strings.Chars_Ptr := 
    Interfaces.C.Strings.New_Char_Array((1..23 => Interfaces.C.nul)); 
+0

私はあなたのコード@ B98を試しましたが、Ptr1宣言で "非ローカルポインタがローカルオブジェクトを指すことができません"というコンパイラエラーが発生していますか? –

+0

これは、あなたのオブジェクトはおそらくいくつかのサブプログラムの中で宣言されていますが、 'chars_ptr'のように(サブプログラムよりも)より外側のレベルで宣言されたポインタ型を介して参照されると言います(Adaライブラリでcouldn 'はるかに "外側"を得る)。これは異なる、そして非常に一般的な問題です。問題を別々に扱えるように、より多くのコンテキストを提供することをお勧めします。特に:ローカルで宣言されたオブジェクトは、プロシージャが終了したときに消えます。したがって、 ''アクセス権 ''を取れば、ぶら下がりポインタを作成します。 Adaはコンパイル時にそのことを防ぎます。 – B98

0

機能新文字列は、あなたが何をしたいのための完璧なツールです。

with Interfaces.C.Strings; use Interfaces.C.Strings; 

procedure Main_Ada is 

Nom : constant chars_Ptr := New_string("Charles Dupont"); 
... 
関連する問題