Ada中数组类型的等价性

时间:2014-04-14 09:50:31

标签: ada subtype equivalence

在尝试将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);

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

第二个问题:

某些数组类型定义具有等效的组件类型。

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

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

2 个答案:

答案 0 :(得分:1)

你可以在Ada中这样说:

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声明都会创建一个新的,不同的类型;没有办法将两种不同的类型视为等价。 (在某些情况下,该语言会自动转换类型,但我认为仅在涉及匿名类型或某些特定类型的情况下,例如&#34;通用整数&#34;。)在这种情况下,但是,没有特别的理由声明像RFC_DATE这样的数组类型。如果您的类型已经是SAP_UC的数组,例如SAP_UC_Array,那么您也可以说

subtype RFC_DATE is SAP_UC_Array (0 .. 7);

因为元素类型RFC_CHAR基本上只是一个&#34;重命名&#34; SAP_UC。 (当然,如果工具生成类型声明,这将无法帮助您。)

答案 1 :(得分: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;

我确信有更好的解决方案。