如何使用引用传递参数将C函数导入Ada?

如何使用引用传递参数将C函数导入Ada?,ada,Ada,我有一个C函数intfunc(inta,int*b),我需要在Ada95中导入和使用它。其中,C函数通常在C中被称为C=func(a,&b) 我一直将C函数导入Ada,但始终避免使用带有传递引用参数的函数,但现在终于到了学习的时候了 我想知道如何在Ada中声明这个函数,还想举一个简单的例子,说明如何在声明的变量中使用它(因为我对访问类型仍然有点模糊) 谢谢大家 在C中,int*b可以表示很多东西。也许它实际上只是一个指向一个变量的指针,但它也可能是一个数组,inta是它的长度。此代码假定int*

我有一个C函数
intfunc(inta,int*b)
,我需要在Ada95中导入和使用它。其中,C函数通常在C中被称为
C=func(a,&b)

我一直将C函数导入Ada,但始终避免使用带有传递引用参数的函数,但现在终于到了学习的时候了

我想知道如何在Ada中声明这个函数,还想举一个简单的例子,说明如何在声明的变量中使用它(因为我对访问类型仍然有点模糊)


谢谢大家

在C中,
int*b
可以表示很多东西。也许它实际上只是一个指向一个变量的指针,但它也可能是一个数组,
inta
是它的长度。此代码假定
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;
您可以对
别名
变量使用
访问
。这是安全的,只要您确保指针不会存储在C端,并且在变量
B
寿命结束后不会被访问。(如果C声明使用
const
关键字,您可以在Ada端使用
access常量
,但这只是ADA2005。)

您还可以使用命名类型:

-- ...
type Int_Access is access C.int;
function Func (A : C.int; B : Int_Access) return C.int;
-- ...
C := Func (A, B'Unchecked_Access);
-- ...
现在我们需要使用
'Unchecked\u Access
,因为Ada通常不允许非本地访问类型(如
Int\u Access
)引用本地变量。如果您知道C代码将如何处理指针(就像您应该做的那样),那么可以使用命名类型来指定不应传递对局部变量的引用

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

Nota bene 2:记录类型和数组无论如何都是通过引用传递的-除非您指定
pragma约定(按副本传递,即您的类型)。在Ada中包装C函数时,这是一个常见的问题。

除了(抄袭flyx)我还提供了一个完整的解决方案:

文件c_thing.c

#include <stdio.h>

int foo (int a, int * b) {
  printf ("A:%d, B %d\n",a, *b);
}
要编译(linux):

运行

./ada_main 
A:42, B 23

C没有引用。这就是为什么你必须使用指针。它们是按值传递的。感谢您的精彩回答,这也澄清了我关于Ada和C之间如何工作的其他一些问题。通过引用传递C接口函数的记录总是让我恼火;与所有C类型一样,C结构也是通过副本传递的。默认情况下,通过复制传递它们会更有意义,如果C函数接受指向结构的指针,则显式传递指针。而且我相当确定
C_pass_by_Value
是GNAT特有的(尽管如果其他Ada编译器采用它,我也不会感到惊讶)。我的名字搞错了。pragma的正确名称是
C\u Pass\u By\u Copy
,它确实是Ada 95中一个特定于蚊虫的pragma。它已添加到Ada 2005中。
gcc -c c_thing.c
gnatmake -c ada_main.adb
gnatbind ada_main.ali
gnatlink ada_main.ali c_thing.o
./ada_main 
A:42, B 23