如何使用pass-by-reference参数将C函数导入Ada?

gjc*_*ann 4 ada

我有一个C函数int func( int a, int* b),我需要在Ada 95中导入和使用.其中C函数通常在C中调用c = func(a, &b);

我一直将C函数导入到Ada中,但总是避免使用带引用参数的函数,但最后还是要学习.

我想知道如何在Ada中声明这个函数,并且还想要一个快速示例,将它与显示的声明变量一起使用(因为我对Access类型仍然有点模糊).

谢谢大家!

fly*_*lyx 8

在C中,int* b可能意味着很多事情.也许它实际上只是指向一个变量的指针,但它也可能是一个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;
Run Code Online (Sandbox Code Playgroud)

您可以使用'Accessaliased变量.只要您确定指针不会存储在C端并在变量的生命周期结束后访问,这是安全的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);
-- ...
Run Code Online (Sandbox Code Playgroud)

现在我们需要使用,'Unchecked_Access因为Ada通常不允许非本地访问类型(as Int_Access)引用局部变量.如果你知道C代码将用指针做什么(就像你应该这样),你可以使用命名类型来指定不应该传递对局部变量的引用.

Nota bene 1:如果你有一个过程(在C中:一个返回的函数void),你可以in out在你的Ada过程声明中使用而不是指定一个通过引用传递的变量access.这样,您根本不需要担心访问类型.和以前一样,你需要确保指针没有存储在C端.

Nota bene 2:记录类型和数组无论如何都是通过引用传递的 - 除非你指定pragma Convention (C_Pass_By_Copy, Your_Type);.在Ada中包装C函数时,这是一个常见的问题.