调用从Ada返回数组的C函数

调用从Ada返回数组的C函数,c,interface,ada,C,Interface,Ada,我有一个C函数,它返回一个整数数组。我如何在Ada中导入它并调用它 关于我失败的尝试,请参见下文 测试c test.adb 编辑: 当我知道它的长度时,我才发现它有效 但是,是否有可能获取一个C数组并在不知道其长度的情况下对其进行迭代?您应该使用数据类型来读取任何类型的内存。 请注意,无约束数组类型希望在内存中的某个位置存储边界 下面是一个使用整型数组类型的示例,它似乎是数据的格式: with SYSTEM; use SYSTEM; function Get_Numbers r

我有一个C函数,它返回一个整数数组。我如何在Ada中导入它并调用它

关于我失败的尝试,请参见下文

测试c

test.adb

编辑: 当我知道它的长度时,我才发现它有效


但是,是否有可能获取一个C数组并在不知道其长度的情况下对其进行迭代?

您应该使用数据类型来读取任何类型的内存。 请注意,无约束数组类型希望在内存中的某个位置存储边界

下面是一个使用整型数组类型的示例,它似乎是数据的格式:

    with SYSTEM; use SYSTEM;

    function Get_Numbers return SYSTEM.Address;
    myReturnValue: SYSTEM.Address;
begin

    myReturnValue := Get_Numbers();
    declare
        arrayContent : Integer_Array (0 .. MAXIMAL_IMAGINABLE_ARRAY_SIZE);
        for arrayContent'Address use myReturnValue;
    begin
        Ada.Text_IO.Put_Line (A (1)'Img);
    end;

不关心堆栈的分配,我们只定义了一个可观察性类型。但不要试图访问最后一个元素

如果你不知道长度,你怎么知道如何停止?如果你有一个哨兵,你应该能够拼凑出一些东西,但是如果你不知道数组的长度是多少,那么你就处于C这个不合适的位置,因为它只是指向对象类型的指针上的语法糖。你有哨兵吗?我有一个C函数,它返回一个整数数组。不,你没有。C函数不能返回数组。你的函数返回一个指向数组第一个元素的指针。继续Keith的观察:当你像这样使用Import和Convention时,编译器将尝试假设你在Ada中所做的与你在C中所做的是等效的,并且它将尝试以一种使事情正常工作的方式传递参数。但是你告诉Ada编译器你有一个返回数组的C函数;因为没有这样的东西,上帝只知道Ada编译器会认为你在尝试做什么。在你的例子中,因为你的C函数返回一个指针,所以让Ada中导入的函数也返回一个访问,或者更好,从Interfaces.C.Pointers的实例化返回一个指针。即使使用Interfaces.C.pointer,您也会面临与从C调用此函数完全相同的问题:何时停止迭代?通常像这样的C函数会传回相关数组的长度;现在Ada2012函数可以有out参数,因此可以使用int*get\u numbersint*len而不是返回结构。
procedure Test is
   type Integer_Array is array (Integer range <>) of Interfaces.C.int;
   pragma Convention (C, Integer_Array);
   for Integer_Array'Component_Size use Interfaces.C.int'Size;

   function Get_Numbers return Integer_Array;
   pragma Import (C, Get_Numbers, "get_numbers");

   A : Integer_Array := Get_Numbers;
begin
   Ada.Text_IO.Put_Line (A (1)'Img);
end Test;
    with SYSTEM; use SYSTEM;

    function Get_Numbers return SYSTEM.Address;
    myReturnValue: SYSTEM.Address;
begin

    myReturnValue := Get_Numbers();
    declare
        arrayContent : Integer_Array (0 .. MAXIMAL_IMAGINABLE_ARRAY_SIZE);
        for arrayContent'Address use myReturnValue;
    begin
        Ada.Text_IO.Put_Line (A (1)'Img);
    end;