Ada将有限的私人类型传递给任务

时间:2017-06-28 21:22:23

标签: types private ada

我有一种情况,我想给一个有限的私有类型的任务,所以它可以调用它上面的各种函数(特别是它是GNAT.Serial_Communications的串行端口)。我似乎无法弄清楚如何使它工作。

我试过直接传递它,直到我必须使用该类型,此时我无法将其复制到已保存的变量:

task body MyTask is
    MyT : LPType;
begin
    accept MyEntry (t : LPType) do
        MyT := t; -- not valid, LPType is limited private
    end MyEntry;
    -- Later I do something using MyT
end MyTask;

由于这不起作用,我尝试将访问权限传递给有限的私有类型,遗憾的是,由于访问的位置,这仍然无效:

procedure MyProcedure is
    MyT : aliased LPType;
    Task : MyTask;
begin
    Initialize (MyT);

    Task.MyEntry (MyT'Access);
end MyProcedure;

我在技术上通过使用Unrestricted_Access来编译它,但这感觉就像一个黑客,根据我的经验,当你使用黑客绕过Ada中的编译器时,编译器有充分的理由强迫你这样做而你犯了一个错误。

所以我的问题是:是否可以通过条目将有限的私人类型传递给任务,或者这只是一个坏主意?

1 个答案:

答案 0 :(得分:4)

在Ada中,limited关键字表示该类型没有与之关联的作业。这与大多数主流语言相反,但考虑类似[物理 - 时钟 - 或RNG - 类型:复制这些没有意义,因此以这种方式对事物进行建模是有意义的。

但是,task构造不能保证与调用其条目的线程位于相同的内存空间中。 - 所以我们在这里遇到一些困难:limited禁止复制,entry需要复制某种类型。

有几种方法可以解决此问题,但考虑到您提供的代码片段,解决方案是使task成为limited类型的组件。< / p>

Package Example is
    Type LP is limited private;
    Function Create return LP;
    Function Create( Value : Integer ) return LP;
    Procedure Print( Object : LP );

Private

    Task Type Printer( Item : not null access LP ) is
        Entry Print;
    End Printer;

    Type LP is limited record
        Value     : Integer := 100;
        Task_Item : Printer(LP'Access);
    end record;

end Example;

Package Body Example is
    Function Create return LP is (others => <>);
    Function Create( Value : Integer ) return LP is
      (Value => Value, others => <>);
    Procedure Print( Object : LP ) is
    Begin
        Object.Task_Item.Print;
    end Print;

    Task Body Printer is
    Begin
        accept Print do
            Null;
        end Print;
        Ada.Text_IO.Put_Line( "Value:" & Integer'Image(Item.Value) );
    End Printer;
end Example;