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;

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

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 这些类型是等价的?

4

2 回答 2

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

subtype RFC_DATE is SAP_UC_Array (0 .. 7);

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

于 2014-04-14T16:38:20.333 回答
0

现在我面临将 Ada-String 转换为 SAP_UC_Array 的挑战。Acutally 一个函数

function toUnicode( adaString : String) return SAP_UC_Array;

是需要的。为此,我想使用 C-Function:

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. 这可能吗?

好吧,我找到了一种解决方法 - 诚然不优雅 - 但它有效。允许按字符读取数组的 AC 函数:

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

带有相应的 Ada 签名:

    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;

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

于 2014-04-16T14:04:21.907 回答