首页 文章

Ada中数组类型的等价性

提问于
浏览
0

在尝试将ADA绑定到第三方C / C库(SAPNWRFCSDK)时,我遇到了数组类型的类型推断问题:

第一个问题:

gcc(gcc -fdump-ada-spec)的Gnat-Binding-Generator为不同的索引范围生成了许多中间命名数组类型:

type anon3115_anon3128_array is array (0 .. 8) of aliased SAP_UC;
type anon3115_anon3131_array is array (0 .. 3) of aliased SAP_UC;
type anon3115_anon3134_array is array (0 .. 12) of aliased SAP_UC;

这些类型用于记录 . 如果我想将这些字段传递给过程或函数,我希望有一个无界的类型签名,例如以下类型:

type SAP_UC_Array is array (Int range <>) of aliased SAP_UC;

但是生成的类型没有这个不能传递的子类型 . 一种解决方案是将记录中的字段声明更改为:

field : SAP_UC_Array(0 .. 8);

但这意味着“处理”生成的绑定文件并更改所有定义 . 是否可以创建具有指定索引范围的命名数组子类型或解决方案?

第二个问题:

某些数组类型定义具有等效的Component类型 .

subtype RFC_CHAR is SAP_UC; 
type RFC_DATE is array (0 .. 7) of aliased RFC_CHAR;

此数组定义不被视为与组件类型SAP_UC的数组等效 . 有可能告诉Ada这些类型是等价的吗?

2 回答

  • 1

    你可以在阿达说这个:

    type SAP_UC_Array is array (Int range <>) of aliased SAP_UC;
    
    subtype anon3115_anon3128_array is SAP_UC_Array (0 .. 8);
    subtype anon3115_anon3131_array is SAP_UC_Array (0 .. 3);
    subtype anon3115_anon3134_array is SAP_UC_Array (0 .. 12);
    

    如果您已经知道这一点,我道歉,但我不知道问题是否只是让Gnat-Binding-Generator生成 subtype 声明 . 我无法帮助你解决GNAT问题 .

    至于第二个问题:每个 type 声明都会创建一个新的,不同的类型;没有办法将两种不同的类型视为等价 . (在某些情况下,语言会自动转换类型,但我认为's only in cases involving anonymous types or certain special types defined by the language such as 2444291 .) In this case, though, there'没有特别的理由声明像 RFC_DATE 这样的数组类型 . 如果你已经有一个 SAP_UC 数组的类型,比如 SAP_UC_Array ,那么你也可以这样做说

    subtype RFC_DATE is SAP_UC_Array (0 .. 7);
    

    因为元素类型RFC_CHAR基本上只是SAP_UC的“重命名” . (当然,如果工具生成类型声明,这对您没有帮助 . )

  • 0

    现在我遇到了将Ada-String转换为SAP_UC_Array的挑战 . 实际上是一个功能

    function toUnicode( adaString : String) return SAP_UC_Array;
    

    需要 . 为此,我想使用C函数:

    SAP_UC const * toUnicode( char const * s)
    {
        UConverter * converter;
        UErrorCode err = U_ZERO_ERROR;
        SAP_UC  * target;
        target = (SAP_UC *) calloc(   strlen(s)+1, sizeof(SAP_UC)  ); // Creating wonderfull Memory Leaks 
        converter = ucnv_open( "8859-1", &err );
        int len = ucnv_toUChars(converter, target, strlen(s)+1, s, strlen(s), &err); 
        ucnv_close( converter );
        return target;
    }
    

    可以映射此函数以产生 access SAP_UC - 与C-Pointer SAP_UC const * 的对应关系:

    function toUnicode (arg1 : Interfaces.C.Strings.chars_ptr) return access SAP_UC;  
       pragma Import (C, toUnicode, "toUnicode");
    

    我用 toUnicode(New_String(adaString)) 调用它并获取对第一个SAP_UC字符的引用 . 但我宁愿回到不受限制的地方 SAP_UC_Array . 这可能吗?

    好吧,我找到了一个解决方案 - 当然不优雅 - 但它确实有效 . 一个C函数,允许以字符方式读出数组:

    SAP_UC getChar(SAP_UC * u, int i)
    {
            return u[i];
    }
    

    与相应的Ada-Signature:

    function getChar(a : access SAP_UC; i: Int) return sapucx_h.SAP_UC;
        pragma Import (C, getChar, "getChar");
    

    在Ada中我有一个函数,它按元素填充给定的SAP_UC_Array:

    function sU( s : String; b : out SAP_UC_Array ) return SAP_UC_Array is
            a : access SAP_UC;
        begin
            a := toUnicode( New_String(s));
            for i in 0 .. Int'Val(s'length) loop
                b(i) := getChar(a,i);
            end loop;
            return b;
        end;
    

    对于我使用的“动态”内存分配:

    function  cU( s : String ) return    SAP_UC_Array
    is
    begin
        declare
            tmp  :  SAP_UC_Array(0 .. s'length);    
        begin
            return sU(s,tmp);
        end;
    end;
    

    我相信有更好的解决方案 .

相关问题