C ではint* b
、多くのことを意味します。おそらく、それは実際には 1 つの変数へのポインターに過ぎませんint a
が、長さの配列である可能性もあります。このコードは、int* b
実際には参照によって渡される単なる値であると想定しています。
with Interfaces.C;
-- ...
package C renames Interfaces.C;
function Func (A : C.int; B : access C.int) return C.int;
pragma Import (Convention => C, Entity => Func,
External_Name => "func");
-- ...
declare
A : C.int := 42;
B : aliased C.int := 23;
C : C.int;
begin
C := Func (A, B'Access);
-- ...
end;
'Access
変数で使用できaliased
ます。これは、ポインターが C 側に格納されず、 variable の有効期間が終了した後にアクセスされないことが確実である限り、安全ですB
。(C 宣言でconst
キーワードを使用する場合access constant
、Ada 側で使用できますが、それは Ada 2005 のみです。)
名前付きタイプを使用することもできます。
-- ...
type Int_Access is access C.int;
function Func (A : C.int; B : Int_Access) return C.int;
-- ...
C := Func (A, B'Unchecked_Access);
-- ...
Ada は通常、非ローカル アクセス タイプ (as ) がローカル変数を参照することを'Unchecked_Access
許可しないため、使用する必要があります。Int_Access
C コードがポインターに対して何をするかがわかっている場合 (当然のように)、名前付き型を使用して、ローカル変数への参照を渡さないように指定できます。
注 1:プロシージャ (C では を返す関数) がある場合、Ada プロシージャ宣言で の代わりに をvoid
使用して、参照渡しされる変数を指定できます。このように、アクセス タイプについてまったく心配する必要はありません。前と同様に、ポインターが C 側に格納されていないことを確認する必要があります。in out
access
注意 2:レコード型と配列は、指定しない限り、とにかく参照によって渡されますpragma Convention (C_Pass_By_Copy, Your_Type);
。これは、Ada で C 関数をラップするときによくある落とし穴です。