You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为接受Union数组的C函数编写Ada绑定的疑难问题求解

Ada绑定C Union数组的问题与解决方案探讨

我正在为某C库开发Ada语言绑定,遇到一个需要接受Union类型数组的C函数。尝试使用Unchecked_Union特性但未定义判别式记录,却因Ada不允许数组元素为无约束类型而失败。

C语言原声明

union argument {
    int32_t i;
    uint32_t u;
    fixed_t f;        // custom 24.8 floating point type, defined as int32_t
    const char *s;    // string
    struct object *o; // custom object type
    uint32_t n;       // may be set as id from struct object (o->id) 
    struct array *a;  // custom array type
    int32_t h;        // file descriptor
};

// ...
foo(.., union argument *args);

GNAT生成的Ada类型

type argument (discr : unsigned := 0) is record
   case discr is
      when 0 =>
         i : aliased x86_64_linux_gnu_bits_stdint_intn_h.int32_t;
      when 1 =>
         u : aliased x86_64_linux_gnu_bits_stdint_uintn_h.uint32_t;
      when 2 =>
         f : aliased fixed_t;
      when 3 =>
         s : Interfaces.C.Strings.chars_ptr;
      when 4 =>
         o : access object;
      when 5 =>
         n : aliased x86_64_linux_gnu_bits_stdint_uintn_h.uint32_t;
      when 6 =>
         a : access array;
      when others =>
         h : aliased x86_64_linux_gnu_bits_stdint_intn_h.int32_t;
   end case;
end record
with Convention => C_Pass_By_Copy,
     Unchecked_Union => True;

我将无符号判别式替换为枚举类型,单个值或具有相同判别式的Unchecked_Union数组均可正常使用,但无法找到在Ada中使用不同Union成员的正确方式。我想到了几种 workaround,但不确定其正确性或是否可在Ada中实现。

观察信息

  • C函数内部最多接受数组中的20个元素
  • 存在一个签名类似的配套函数,使用可变参数而非Union类型数组,可变参数会被转换为该Union类型

方案1

使用可变参数版本,在Ada中生成多个不同参数数量/类型组合的重载函数。据我理解,这需要20*8个函数定义,工作量极大。

方案2

编写导入函数时使用确定的Union类型,然后通过Unchecked_Conversion在值之间进行转换,例如array (Integer range 0..19) of argument(4),再将数组元素转换为不同类型。

方案3

利用数组最大尺寸,分配(aliased)一块20*64字节(Union大小)的内存块,编写辅助过程在正确的内存位置读写正确的值,然后将该内存块以'Access或'Address形式传递给C函数。此时函数参数为access my_blob或仅System.Address。

我个人倾向于方案3,但这需要大量的研究、开发与测试工作,因此询问是否存在更优的实现方式。

附:我认为这是Ada的一个缺陷,因为ARM B.3.3 §14/2明确规定“所有Unchecked_Union类型的对象大小相同”,因此应当可以创建无需定义判别式的Unchecked_Union数组。但我理解这是为了代码安全性而设计的。

内容的提问来源于stack exchange,提问作者servik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 02:37:36