艾达 Remote_Types 错误 "illegal overriding of subprogram inherited from interface"

Ada Remote_Types error "illegal overriding of subprogram inherited from interface"

我正在开发完全使用 Ada 和 DSA 的 DBMS(数据库管理软件)。 但是我遇到了一些问题;行作为文档(MongoDB 样式)实现,并且它们是受保护的接口,然后在与受保护类型相同的包中实现。 我必须先把它变成一个接口,这样它才有可能有一个远程访问类型(受保护的类型不能有远程访问类型,因为它们没有被标记)。 对于所有被覆盖的函数(但不是过程),我收到相同的消息:

safira-documents.ads:845:27: illegal overriding of subprogram inherited from interface
safira-documents.ads:845:27: first formal of "Is_Version_Controlled" declared at line 737 must be of mode "in" or access-to-constant
safira-documents.ads:856:27: illegal overriding of subprogram inherited from interface
safira-documents.ads:856:27: first formal of "Get_Contents" declared at line 753 must be of mode "in" or access-to-constant
safira-documents.ads:861:27: illegal overriding of subprogram inherited from interface
safira-documents.ads:861:27: first formal of "Get_Version" declared at line 760 must be of mode "in" or access-to-constant
safira-documents.ads:880:27: illegal overriding of subprogram inherited from interface
safira-documents.ads:880:27: first formal of "Has_Key" declared at line 785 must be of mode "in" or access-to-constant
safira-documents.ads:888:27: illegal overriding of subprogram inherited from interface
safira-documents.ads:888:27: first formal of "Get_Value" declared at line 795 must be of mode "in" or access-to-constant
safira-documents.ads:900:27: illegal overriding of subprogram inherited from interface
safira-documents.ads:900:27: first formal of "Get_Id" declared at line 810 must be of mode "in" or access-to-constant
safira-documents.ads:902:27: illegal overriding of subprogram inherited from interface
safira-documents.ads:902:27: first formal of "Get_Location" declared at line 812 must be of mode "in" or access-to-constant
safira-documents.ads:904:27: illegal overriding of subprogram inherited from interface
safira-documents.ads:904:27: first formal of "Database" declared at line 816 must be of mode "in" or access-to-constant
safira-documents.ads:906:27: illegal overriding of subprogram inherited from interface
safira-documents.ads:906:27: first formal of "Collection" declared at line 820 must be of mode "in" or access-to-constant
safira-documents.ads:908:27: illegal overriding of subprogram inherited from interface
safira-documents.ads:908:27: first formal of "Get_Creation_Time_As_Dictionary" declared at line 824 must be of mode "in" or access-to-constant
safira-documents.ads:911:27: illegal overriding of subprogram inherited from interface
safira-documents.ads:911:27: first formal of "Get_Last_Update_Time_As_Dictionary" declared at line 828 must be of mode "in" or access-to-constant
gprbuild: *** compilation phase failed

相关代码是这样的:

package Safira.Documents with Remote_Types, Spark_Mode => On, Elaborate_Body is
   
   type Update_Value_Operation is 
     access procedure 
       (K : in     Key;
        V : in out Value);
   
   type Base_Document is protected interface;
   -- Documents live in Storage_Nodes only. Clients access them through remote
   -- access types.
   -- This allows them to be declared as protected types with trustworthy atomic
   --  operations that won't corrupt their content.
   
   type Base_Document_Xs is access all Base_Document'Class;
   
   -- << Many subprograms for the interface here >>
   
   protected type Document is new Base_Document with
      
      overriding function Is_Version_Controlled return Boolean;
   
      overriding procedure Set_Mirror 
        (N : in     Nodename_String.Bounded_String);
   
      overriding procedure Remove_From_Mirror 
        (N : in     Nodename_String.Bounded_String);
   
      overriding procedure Set_Contents 
        (D : in     Dictionary'Class);
   
      overriding function Get_Contents return Dictionary'Class;
   
      overriding procedure Revert_To 
        (Version : in     Document_Version);
   
      overriding function Get_Version 
        (Version : in     Document_Version)
         return Dictionary'Class;
   
      overriding procedure Delete_Version 
        (Version : in     Document_Version);
   
      overriding procedure Define_New_Origin 
        (From : in     Document_Version);
   
      overriding procedure Delete_Entire_History;
   
      overriding procedure Clone_From 
        (Origin  : access Document);
   
      overriding procedure Clone_From 
        (Origin  : access Document;
         Version : in     Document_Version);
   
      overriding function Has_Key 
        (K : in     Key) 
         return Boolean;
   
      overriding procedure Set_Value 
        (K : in     Key;
         V : in     Value'Class);
   
      overriding function Get_Value 
        (K : in     Key) 
         return Value'Class;
   
      overriding procedure Update_Value 
        (K : in     Key;
         V : in     Value'Class);
   
      overriding procedure Update_Value 
        (K  : in     Key;
         Op : in     Update_Value_Operation);
   
      overriding function Get_Id return Document_Id;
   
      overriding function Get_Location return Nodename_String.Bounded_String;
   
      overriding function Database return Blueprint_String.Bounded_String;
   
      overriding function Collection return Blueprint_String.Bounded_String;
   
      overriding function Get_Creation_Time_As_Dictionary 
        return Dictionary'Class;
   
      overriding function Get_Last_Update_Time_As_Dictionary 
        return Dictionary'Class;
      
   private
      
      Contents : Dictionary;
      
   end Document;

end Safira.Documents;

将那些 access 参数转换为接口规范中的 in 参数(显然)可以解决问题。但我不知道这是否会破坏远程功能。我在互联网上找到的所有 Remote_Types 示例都使用了远程类型方法的访问参数。

显然,接口的函数需要访问常量参数(即实际参数),我没有要求它,所以我确定这是一些 Ada 默认值security/safety 特征。

现在...我可以在不破坏远程功能的情况下将 access 参数更改为 in 参数吗?如果不是,有没有办法避免这种默认行为(换句话说,让他们访问可变参数)? 我为 Remote_Types 找到的所有示例都使用了 access 参数,所以恐怕我将它们变成 in 参数的解决方案可能会使它们成为正常的(非远程)方法,这将呈现这个包在分布式应用程序中作为 Remote_Types 无用。我可以试着让它变得纯粹,但不知道是否可以轻松完成。

P.S.: 应该会在以后(准备好)开源,所以如果我真的需要,我现在可以发布整个文件或整个项目。 我不喜欢在项目准备就绪之前发布我的项目,但如果有人需要为此找到解决方案...我会这样做。

您没有提供受保护函数的配置文件,但您似乎错过了访问参数的 constant 关键字:

type PI is protected interface;
function Is_Version (Self : access constant PI) return Boolean
   is abstract;

protected type D is new PI with
     overriding function Is_Version return Boolean;
private
   Ok : Boolean;
end D;

关于 inaccess 对于远程类型,应该没有 interface/protected 类型的区别,因为在 Ada 中它们无论如何都是通过引用传递的。